2015-01-29 3 views
5

Это, пожалуй, очень простой вопрос, но, тем не менее, он, похоже, не был покрыт SO.Haskell- (объявление типа), что такое «а»?

Я недавно взял Haskell и до сих пор не тип декларация состояла в основном из следующих:

Int 
Bool 
Float 
etc, etc 

Теперь я получаю в списки и я вижу объявление типа, которые используют a, например, в следующей функции что перебирает ассоциативный список:

contains :: Int -> [(Int,a)] -> [a] 
contains x list = [values | (key,values)<-list, x==key] 

Может кто-то предоставить объяснение относительно того, что это a, и как это работает? Кажется, что из наблюдения он представляет каждый тип. Означает ли это, что я могу ввести любой список любого типа в качестве параметра?

ответ

12

Да, вы правы, он представляет собой «любой тип» - ограничение состоит в том, что все a s в заданной сигнатуре типа должны быть разрешены к одному типу. Таким образом, вы можете ввести список любого типа, но когда вы используете contains для поиска значения в списке, значение, которое вы ищете, должно быть того же типа, что и элементы списка, что, конечно, имеет смысл.

+8

Так же важно, что 'a' не является особенным: * любой * идентификатор нижнего регистра означает это. Это переменная типа *, и в одной и той же сигнатуре существует множество разных переменных типа. Например, 'const :: a -> b -> a' принимает два аргумента, каждый из которых имеет тип, и возвращает значение с тем же типом, что и его первый вход. – amalloy

+2

Я вижу, его очень общее. Поэтому, я думаю, в большинстве случаев 'a' обычно представляет элементы, которые моя функция действительно не использует или не меняет слишком много. – Bolboa

+1

@Bolboa: Да, это тесно связано с понятием «дженерики» на других языках. И да, если тип полностью общий, мало что можно сделать непосредственно для самого значения. У Haskell есть способ предоставить больше информации о типе (например, «можно сравнить для равенства», «можно печатать», «можно обрабатывать как число»), что позволяет вам делать больше обработки значений ; если вы заинтересованы в этом, тогда найдите «классы» в документации или учебнике. – psmears

1

В Haskell, прописные типы конкретных типов (Int, Bool) или конструкторы типов (Maybe, Either), тогда как в нижнем регистре типа являются переменные типа. Функция неявно общее во всех переменных типа, которые он использует, так это:

contains :: Int -> [(Int, a)] -> [a] 

Является ли сокращение для этого *:

contains :: forall a. Int -> [(Int, a)] -> [a] 

В C++, forall пишется template:

template<typename a> 
list<a> contains(int, list<pair<int, a>>); 

В Java и C#, это написано с помощью угловых кронштейнов:

list<a> contains<a>(int, list<pair<int, a>>); 

Конечно, в этих языках, переменные общего типа часто называют T, U, V, в то время как в Haskell они часто называют a, b, c. Это просто отличие конвенции.

* Этот синтаксис включен флагом -XExplicitForAll в GHC, а также другими расширениями.

+0

Гораздо более полезно: '-XScopedTypeVariables'. Кроме того, C++-шаблоны, по-видимому, по своей сути отличаются от переменных типа Haskell/ML/... или даже Java Generics. – dfeuer

Смежные вопросы