Хаскелл Помощью FlatMap

Я новичок, заинтересованный в Haskell, и я пытался реализовать flatmap (>>=) самостоятельно, чтобы лучше понять его. В настоящее время у меня

flatmap :: (t -> a) -> [t] -> [a]  
flatmap _ [] = []  
flatmap f (x:xs) = f x : flatmap f xs  

который реализует часть "карта", но не"плоский".
Большую часть изменений я привести в уныние и довольно informationless

Occurs check: cannot construct the infinite type: a = [a]  
    When generalising the type(s) for `flatmap' 

ошибка.

что я упустил?

1 ответов


такая ошибка возникает, когда указанная подпись типа не соответствует фактическому типу функции. Поскольку вы не показали код, который вызывает ошибку, я должен угадать, но я предполагаю, что вы изменили его на что-то вроде этого:

flatmap _ [] = []  
flatmap f (x:xs) = f x ++ flatmap f xs

что, как оказалось, совершенно правильно. Однако, если вы забыли также изменить подпись типа, произойдет следующее:

type checker видит, что вы используете ++ по результатам f x и flatmap f xs. С ++ работает на двух списках одного и того же типа, type checker теперь знает, что оба выражения должны оцениваться в списки одного и того же типа. Теперь typechecker также знает, что flatmap f xs возвращает результат типа [a], так что f x также должен иметь тип [a]. Однако в сигнатуре типа говорится, что f имеет тип t -> a, так что f x должно иметь тип a. Это приводит type checker к выводу, что [a] = a что является противоречием и приводит к сообщению об ошибке, которое вы видеть.

если вы измените подпись типа flatmap :: (t -> [a]) -> [t] -> [a] (или удалить его), он будет работать.