2014-04-03 4 views
0

У меня возникли трудности с пониманием типов в haskell. Рассмотрим следующие функции и рассмотрим их типы.Признание типов haskell

reduce f s [] = s 
reduce f s (x:xs) = f x (reduce f s xs) 

for m n f s = if m>n then s else for (m+1) n f (f m s) 

comp f g x y = f x (g x y) 

iter 0 f s = s 
iter n f s = iter (n-1) f (f s) 

Мы бы иметь что-то вроде:

reduce :: (t1 -> t -> t) -> t -> [t1] -> t 
for :: (Ord a, Num a) => a -> a -> (a -> t -> t) -> t -> t 
comp :: (t -> t2 -> t3) -> (t -> t1 -> t2) -> t -> t1 -> t3 
iter :: (Num t) => t -> (t1 -> t1) -> t1 -> t1 

То, что я не ясно понять, что в функции уменьшения е принимает два параметра, и для функции F снова принимает два параметра. Все, что я вижу, это то, что он принимает только один. Хорошо, если это будет что-то вроде этого:

for m n f s = if m>n then s else for (m+1) n f m n 

Было бы более очевидным и легко признать, что е действительно принимает два параметра.

Мне интересно, существуют ли какие-либо способы или методы для вывода типов функций в haskell. В дополнение к этим примерам я бы попросил несколько разных примеров, чтобы я мог преодолеть эти трудности.

EDIT: В моих определениях случая функций заданы, я просто пытаюсь вывести их тип

+3

Вы Tackling это неправильно. Всегда _start_ от типов и того, как вы планируете использовать конечную функцию, а затем подумайте о реализации. «О» в 'for' function' f' снова принимает два параметра. Все, что я вижу, это то, что он принимает только один »: насколько яснее, чем' (f m s) 'он может получить? Вы буквально кормите функцию двумя аргументами вручную. Или что вы имеете в виду? – leftaroundabout

+0

Да, кажется, что так, но когда он приходит 'f (f m s)' он меня смущает – user2878007

+0

'f (f m s)' является частью 'for (m + 1) n f (f m s)'. первый 'f' применяется к рекурсивному вызову' for'. Всегда помещайте типы в определения верхнего уровня. – Simon

ответ

6

Где вы делаете мысленную ошибку в рассмотрении даже f (f m s). То есть не подвыражение определения for: напомните, что приложение функции анализируется слева. Так

for (m+1) n f (f m s) 
≡ (for (m+1)) n f (f m s) 
≡ (for (m+1) n) f (f m s) 
≡ (for (m+1) n f) (f m s) 
≇ (for (m+1) n) (f (f m s)) 
≇ for (m+1) (n f (f m s)) 
≇ for ((m+1) n f (f m s)) 

Последнее неравенство, вероятно, самым очевидным, потому что вы бы применения функции (m+1) в три аргумента ..., что уверен, выглядит очень маловероятно.

Если вам нужна «умственную parenthesising» для понимания функции, это обычно лучше, чтобы поместить их вокруг каждого аргумента функции:

for (m+1) n f (f m s) 
≡ for (m+1) 
     (n) 
     (f) 
     (f m s) 

и, если это поможет вам, потому что это больше похоже на то, что вы есть в основных языках, вы можете также uncurry все:

≅ for (m+1, n, f, f(m,s)) 

(хотя вы бы лучше забыть о том, что один быстро)


Кстати: если вы видите функцию, примененную только к одному аргументу, это не означает, что тип функции имеет только один аргумент. Фактически, основная сила синтаксиса карнавала Haskell заключается в том, что вы можете легко сделать частичное приложение: например.

Prelude>: т взять
взять :: Int -> [а] -> [а]
Prelude>: т взять 3
взять 3 :: [а] -> [а]
Prelude> карта (взять 3) [ "looooong", "даже loonger", "очень долго"]
[ "Лоо", "накануне", "тер"]

Вы видите, что я имею только применяется take к одному аргументу, а другой - автоматически из списка по map.

Другой пример, с секциями оператора,

Прелюдия>: т (+)
(+) :: Num а => а -> а -> а
Прелюдия>: т (+ 1)
(+ 1) :: Num а => а -> а
Прелюдия> карта (+ 1) [4,5,6]
[5,6,7]

+0

Спасибо за ваше объяснение – user2878007

+0

Это частичное приложение. Частичная оценка - это метод оптимизации времени компиляции. – Carl

+0

@ Карл: Спасибо. Хотя, я бы не сказал, что это оптимизация, это очень общий метод с большим количеством приложений. Но то, что я описал, действительно не является частичной оценкой, поэтому вы правы, чтобы указать на это. – leftaroundabout

1

тип f в следующем определение довольно легко вывести

for m n f s = if m>n then s else for (m+1) n f (f m s) 

Это можно переписать (для clearity) в

for m n f s 
    | m>n  = s 
    | otherwise = for (m+1) n f (f m s) 
  1. for (m+1) n f (f m s) является вызов for,

  2. , что означает f m s потребности имеет такой же тип, как s,

  3. это требует f чтобы иметь тип t1 -> t -> t
    (t1 для m и t для s)

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