подпись типа Haskell - PullRequest
       56

подпись типа Haskell

1 голос
/ 09 октября 2019
cow :: (Eq a) => a -> a -> [a] -> Bool
cow x y z = x && y `elem` z

 foo ::
 foo x y z = x `elem` y && y `elem` z

 bar::
 bar x y = case y of
    Nothing -> x
    Just z  -> x + z

Я не знаю, какой должна быть подпись типа.

1 Ответ

3 голосов
/ 09 октября 2019

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

Поскольку сигнатура типа вашей функции cow не совсем верна, мы покажем, как получить сигнатуру типаcow, а затем оставьте два других в качестве упражнений.

Мы видим, что cow здесь имеет три параметра: x, y и z. На данный момент мы мало знаем о x, y и z. Поэтому мы назначим переменную другого типа для этих переменных. Итак, x :: a, y :: b и z :: c.

Далее мы можем начать получать типы. Определение функции cow:

cow x y z = x && y `elem` z

можно записать в более каноническом формате как:

cow x y z = (&&) x (elem y z)

Таким образом, мы видим, что здесь используются две функции: (&&) :: Bool -> Bool -> Bool и elem :: (Eq e, Foldable f) => e -> f e -> Bool, здесь мы используем e вместо f, чтобы избежать «именных столкновений» с нашимипеременная уже определенного типа a. Поскольку мы используем x в качестве аргумента функции (&&) :: Bool -> Bool -> Bool, мы знаем, что x должен иметь тип Bool, и, таким образом, a ~ Bool (a - тот же тип, что и Bool). Более того, мы знаем, что (&&) x :: Bool -> Bool.

Далее мы видим, что мы называем elem :: (Eq e, Foldable f) => e -> f e -> Bool. Таким образом, это означает, что y, который является первым параметром, примененным к elem, имеет тип e, и, следовательно, b ~ e.

Кроме того, это означает, что elem x имеет тип (Eq e, Foldable f) => f e -> Boolи мы применяем эту функцию к параметру z. Таким образом, это означает, что c ~ (Eq e, Foldable f) => f e и тип elem y z равен Bool.

Поскольку тип elem y z равен Bool, это соответствует функции (&&) x, и, таким образом,тип (&&) x (elem y z), таким образом, равен Bool.

Таким образом, мы получили:

x :: Bool
y :: e
z :: f e

с ограничениями типов Eq e и Foldable f. Таким образом, это означает, что cow имеет функцию:

cow :: (Eq e, Foldable f) => Bool -> e -> f e -> Bool
cow x y z = x && y `elem` z
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...