Хаскелл Помощью 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]
(или удалить его), он будет работать.