Как определить тип константных выражений в Haskell? - PullRequest
0 голосов
/ 09 июня 2009

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

Для каждого из следующих выражений укажите свой тип в Haskell (для выражения, которое имеет много типов, просто укажите один тип).

(True, "hello", 42)
[42, 4, 2]
length [True]
filter even

Лично я думаю, что ответом на один и два будет кортеж bool, String и int и список целых чисел соответственно, правильно ли это предположить? и, во-вторых, как бы вы ответили на 3 и 4, я уверен, что длина True просто выводит список всех элементов этой длины, и этот фильтр даже просто изменяет список целых чисел в список всех четных чисел, хотя как Могу ли я показать это как ответ?

Ответы [ 3 ]

6 голосов
/ 09 июня 2009

Если вы хотите отключить типы переменных в автономном режиме с помощью ghci, введите
:t выражение

если вы хотите создать переменные в ghci, вы должны использовать let, не используя 'in' (как в нотации do для монад, я не знаю, видели ли вы их еще):
let var = expr

Если вы проверите все это самостоятельно, вы сможете легче запомнить его для экзаменов. (удачи в этом;))

1 голос
/ 13 июня 2009

Если быть точным, тип [42, 4, 2] будет

Num a => [a]

Это потому, что целочисленный литерал в Haskell трактуется как имеющий неявный «fromIntegral» перед ним, поэтому реальное выражение - [fromIntegral 42, fromIntegral 4, fromIntegral 2].

"fromIntegral" является частью класса Num и имеет тип

fromIntegral :: (Integral a, Num b) => a -> b

Это говорит о том, что он преобразует экземпляр некоторого интегрального типа (то есть Int или Integer) в произвольный другой числовой тип (Int, Float, Double, Complex ...). Вот почему вы можете сказать что-то вроде «43.2 + 1», не получая ошибку типа.

"length [True]" будет иметь тип Int, потому что "length" имеет тип "[a] -> Int", и предоставляется аргумент (список Bool).

«Фильтр даже» немного сложнее. Начнем с типа «фильтр»:

filter :: (a -> Bool) -> [a] -> [a]

Первый параметр (бит в скобках) сам по себе является функцией, которая принимает элемент списка и возвращает Bool. Помните, что оператор «->» в типах Haskell является ассоциативным справа, поэтому, если вы заключите подразумеваемые скобки, вы увидите, что тип:

filter :: (a -> Bool) -> ([a] -> [a])

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

even :: (Integral a) => a -> Bool

Это вносит небольшую морщинку: «даже» требует, чтобы его аргумент был целочисленным типом (т. Е. Int или Integer, как указано выше), поэтому это ограничение должно быть распространено на результат. Если бы не было, вы могли бы написать это:

filter even "foo"

Следовательно, ответ:

filter even :: (Integral a) => [a] -> [a]

Вы можете видеть, что ограничение Integral происходит от типа "even", а остальная часть типа - от "filter".

1 голос
/ 09 июня 2009

length [True] будет Int и вернет 1. Вы можете проверить это с помощью ghci или lambdabot.

фильтр даже будет (Integral a) => [a] -> [a] например, [Int] -> [Int]

И я думаю, что это бессмысленно, потому что lambdabot может рассказать вам все эти вещи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...