2014-12-02 5 views
4

Я играю с Control.Applicative, и я понимаю, что не понимаю всего с системой типа Haskell.Понимание системы типа Haskell в контексте прикладных программ

Вот мой эксперимент в GHCI:

λ :t (<*>) 
(<*>) :: Applicative f => f (a -> b) -> f a -> f b 

λ :t (<*>) (pure 2) 
(<*>) (pure 2) :: (Num (a -> b), Applicative f) => f a -> f b 

тип первого аргумента <*> является f (a -> b).

  • Почему это выражение правильное?
  • Как это можно объединить с (pure 2), так как константа 2 не относится к типу a -> b?
  • Что означает Num (a -> b)? Как может быть функция, имеющая тип a -> b, экземпляр Num?
+9

'Num (a -> b)' в контексте не означает, что * есть * экземпляр 'Num' для' a -> b'. Это означает, что «если есть *» * экземпляр 'Num' для' a -> b', тогда выражение будет иметь этот тип. –

+1

Кроме того, константа является литералом и поэтому имеет тип '2 :: Num a => a'. – Zeta

+1

try next: ': t (<*>) (pure (2 :: Int))' – viorior

ответ

7

Первый аргумент <*> должен быть f (a -> b). Так что дано (<*>) (pure x), это хорошо типизировано при условии, что x - это какая-то функция.

Тип 2: Num a => a. Другими словами, 2 может быть любым возможным типом, при условии, что это пример Num.

Так что в вашем выражении (<*>) (pure 2), это хорошо набирается при условии, что тип 2 является типом функции, а тип функции имеет Num экземпляр.

Конечно, почти нет причин, по которым вы хотели бы, чтобы функция имела экземпляр Num. Но компилятор этого не знает. Все это говорит о том, что , если был такой экземпляр, тогда выражение получило бы типичный характер.

(Это похоже на ошибку вы иногда видите, где компилятор хочет какой-то тип, чтобы быть экземпляром Integral и Fractional одновременно. Для человека, это бессмысленное сочетание. К машине, они просто две обыкновенные классы ...)

+1

Наличие функций, которые ведут себя как числа, на самом деле очень полезно иногда. Это не стандартный пример, но он имеет смысл. Что-то вроде 'instance (Num b) => Num (a -> b), где f + g = \ x -> fx + fy' и т. Д. Это позволяет вам писать такие вещи, как' (sin + cos) 0,1' с очевидным имея в виду. – augustss

+0

Как может быть '' '' '' типа функции? Как бы вы это назвали? Являются ли числовые литералы частью класса Num в определении? – z1naOK9nu8iY5A

+0

@augustss Я сказал «почти». ;-) – MathematicalOrchid