Я просто ввел ваш код в GHCi и попросил его сообщить мне тип:
Prelude> :{
Prelude| data Letter a =
Prelude| A a
Prelude| | B a
Prelude| | C String
Prelude| deriving (Show)
Prelude| :}
Prelude> :{
Prelude| getConstructor x
Prelude| | x == "a" = A
Prelude| | x == "b" = B
Prelude| | otherwise = C
Prelude| :}
Prelude> :t getConstructor
getConstructor :: [Char] -> String -> Letter String
Это имеет смысл, потому что для этого требуется [Char]
(он же String
- это x
аргумент) и возвращает один из A
, B
и C
, которые являются конструкторами для Letter
.Будучи конструкторами, они также являются функциями - в случае C
тип явно String -> Letter a
, тогда как A
и B
имеют тип a -> Letter a
.Поскольку это все возможные возвращаемые значения getConstructor
, они должны быть одного типа - единственный способ для этого - если a
всегда равен String
.Это дает нам тип getConstructor
как String -> (String -> Letter String)
, что в точности соответствует тому, что GHCi говорит выше (с небольшим переписыванием).