2015-05-09 7 views
-1

Вот коды:Почему такая рекурсивная функция Haskell не работает?

rep' :: Int -> a -> [a] 
rep' 0 x = [] 
rep' n x = x:rep'(n-1, x) 

я пытался переписать так:

rep' :: Int -> a -> [a] 
rep' 0 x = [] 
rep' n x = x:(rep' n-1 x) 

но он не работает.

baby.hs:3:15-20: Couldn't match expected type ‘[a]’ with actual type ‘a0 -> [a0]’ … 
    Relevant bindings include 
     x :: a (bound at /Users/hanfeisun/Workspace/haskell/baby.hs:3:8) 
     rep' :: Int -> a -> [a] 
     (bound at /Users/hanfeisun/Workspace/haskell/baby.hs:2:1) 
    Probable cause: ‘rep'’ is applied to too few arguments 
    In the first argument of ‘(-)’, namely ‘rep' n’ 
    In the second argument of ‘(:)’, namely ‘(rep' n - 1 x)’ 
Compilation failed. 
λ> 

У кого-нибудь есть идеи об этом?

+0

Функции Haskell называются 'fun arg1 arg2 ...' not 'fun (arg1, arg2, ...)'. – AJFarmar

+0

@AJFarmar. Оба они совершенно законны в зависимости от типа «забавы». Важно то, что вы вызываете функцию того же типа, что и вы ее определили. – sepp2k

+0

@ sepp2k Я понимаю это, но, ради изучения Haskell, идеально, чтобы показать новичкам метод карри. – AJFarmar

ответ

10

Haskell выражает свои проблемы и ожидания в сообщениях об ошибках, как этот

Prelude> :{ 
Prelude|  let 
Prelude|  { 
Prelude|   rep' :: Int -> a -> [a]; 
Prelude|   rep' 0 x = []; 
Prelude|   rep' n x = x:rep' (n-1, x); 
Prelude|  } 
Prelude| :} 

<interactive>:73:22: 
    Couldn't match expected type `[a]' with actual type `a0 -> [a0]' 
    In the return type of a call of rep' 
    Probable cause: rep' is applied to too few arguments 
    In the second argument of `(:)', namely `rep' (n - 1, x)' 
    In the expression: x : rep' (n - 1, x) 

<interactive>:73:27: 
    Couldn't match expected type `Int' with actual type `(Int, a)' 
    In the first argument of rep', namely `(n - 1, x)' 
    In the second argument of `(:)', namely `rep' (n - 1, x)' 
    In the expression: x : rep' (n - 1, x) 

В первом разделе

Couldn't match expected type `[a]' with actual type `a0 -> [a0]' 
    In the return type of a call of rep' 
    Probable cause: rep' is applied to too few arguments 

говорит, что вы объявили возвращаемый тип rep' в [a], но он возвращает a0 -> [a0], что означает, что он возвращает частично примененную функцию. Возможная проблема также дается вам как намек

Probable cause: rep' is applied to too few arguments 

так что вы могли бы быть меньше, проходящей аргументы функции rep'. И в следующем разделе, линии

Couldn't match expected type `Int' with actual type `(Int, a)' 

говорит, что он ожидает Int, но он получил (Int, a). В Haskell, когда вы говорите (n-1, x), он рассматривается как объект кортежа с двумя элементами в нем. Итак, вы на самом деле вызываете rep' с одним кортежем, а не с двумя параметрами.

Чтобы действительно вызвать rep' с двумя параметрами, которые вы можете сделать, как этот

rep' n x = x:rep' (n-1) x 

Теперь вы вызываете rep' с двумя аргументами, (n-1) и x.

Prelude> :{ 
Prelude|  let 
Prelude|  { 
Prelude|   rep' :: Int -> a -> [a]; 
Prelude|   rep' 0 x = []; 
Prelude|   rep' n x = x:rep' (n-1) x; 
Prelude|  } 
Prelude| :} 
Prelude> rep' 5 100 
[100,100,100,100,100] 
5

Первый аргумент rep' должен быть Int, но когда вы называете его rep' (n-1, x), первым и единственным аргументом является кортеж.

Смежные вопросы