Это может не помочь для домашней работы, но вы на самом деле можете написать такую декларацию. Вы просто должны включить -XFlexibleInstances
, чтобы сделать это. По крайней мере, в GHC вы можете сделать это, поместив прагму вверху вашего файла:
{-# LANGUAGE FlexibleInstances #-}
Если вы внимательно посмотрите на полученное сообщение об ошибке, оно говорит что-то вроде «Используйте -XF FlexibleInstances, если вы хотите отключить это».
В этом конкретном случае вам также необходимо включить UndecidableInstances
и OverlappingInstances
:
{-# LANGUAGE FlexibleInstances, UndecidableInstances, OverlappingInstances #-}
Вам нужен FlexibleInstances
, потому что стандартный Haskell не допускает экземпляры в любой форме, где переменная типа появляется более одного раза в голове. Это совершенно нормально - это одно из самых распространенных расширений (согласно этот вопрос ).
Вам нужен UndecidableInstances
, потому что объявление вашего экземпляра потенциально может привести к тому, что средство проверки типов будет работать постоянно. Я думаю, что использование UndecidableInstances
предотвращает это, ограничивая, насколько глубоко он будет проверять при попытке уменьшить экземпляр. Это обычно - в том числе и в этом случае - хорошо, но теоретически может определить, проходит ли конкретная программа проверки типа в зависимости от реализации . Тем не менее, это должно работать в вашем случае.
Как отметил Хаммар, вам нужно включить OverlappingInstances
, потому что "контекст" экземпляра игнорируется при проверке, перекрываются ли они. В этом случае контекстом является бит Num a
. Таким образом, экземпляры - для проверки, перекрываются ли они - читаются как instance Truthy a...
и перекрываются со всем. С включенным OverlappingInstances
вам просто нужно иметь один экземпляр, который наиболее специфичен для этой работы.