Я пытался получить бесконечный список чисел Фибоначчи в Haskell, но следующий код не компилируется:Haskell Фибоначчи - не может построить бесконечный тип: a0 = [a0]
fib1 x = fib1 (x : (last $ init x) + (last x))
result1 = fib1 [1,2]
в конце концов, я получил его работать с этим кодом:
fib2 x y = head y : fib2 y (zipWith (+) x y)
result2 = fib2 [0,1] [1,1]
Тем не менее, я не понимаю, почему первый фрагмент кода не компилировать. Ошибка ниже. Я просто ищу ответ, почему первый не компилируется, но второй делает.
p2.hs:3:16:
Occurs check: cannot construct the infinite type: a0 = [a0]
In the first argument of `(:)', namely `x'
In the first argument of `fib1', namely
`(x : (last $ init x) + (last x))'
In the expression: fib1 (x : (last $ init x) + (last x))
p2.hs:3:21:
Occurs check: cannot construct the infinite type: a0 = [a0]
In the first argument of `(+)', namely `(last $ init x)'
In the second argument of `(:)', namely
`(last $ init x) + (last x)'
In the first argument of `fib1', namely
`(x : (last $ init x) + (last x))'
p2.hs:3:44:
Occurs check: cannot construct the infinite type: a0 = [a0]
Expected type: [[a0]]
Actual type: [a0]
In the first argument of `last', namely `x'
In the second argument of `(+)', namely `(last x)'
In the second argument of `(:)', namely
`(last $ init x) + (last x)' Failed, modules loaded: none.
Хорошее объяснение. @Jeff Lins, первый шаг, когда вы получаете такие проблемы, это добавить объявления типов к вашим функциям. (или даже привычка всегда добавлять их). Затем либо вы получаете более точные ошибки от компилятора, либо, как в этом случае, сами находите проблему. – drRobertz
Я не уверен, что понимаю это. Прежде чем я разместил вопрос, я попытался предоставить аннотацию следующего типа: fib1 :: Num a => [a] -> [a]. Но, очевидно, это не сработало. Я не понимаю, почему он изменяет правильную сторону [[a]]. Потому что [a]: [a] должен привести только к [a]. Почему он переносит список в другой список? –
@JeffLins У вас есть тип '(:)' wrong; это не '[a] -> [a] -> [a]' but 'a -> [a] -> [a]'. Но даже тогда у вас возникнет проблема, потому что 'last' и' init' не возвращают список (очевидно). –