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
Я не знаю, какой должна быть подпись типа.
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
Я не знаю, какой должна быть подпись типа.
Для того, чтобы определить тип подписи. Вам не нужно знать, что делает функция. Вы можете использовать сигнатуры типов функций, которые вы используете, и делать выводы об этом.
Поскольку сигнатура типа вашей функции 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
Foldable f
может быть специализировано для []
, давая Bool -> a -> [a] -> Bool
- person Jon Purdy; 09.10.2019
x
в предлагаемой подписи в вопросе.
- person Willem Van Onsem; 09.10.2019
elem
,(+)
и(&&)
. - person Willem Van Onsem   schedule 09.10.2019cow
тоже неправильно. - person amalloy   schedule 09.10.2019