Что [] (перечислите конструктора) в Haskell?

У меня Есть проблемы при понимании функторов, конкретно что конкретный тип находится в LYAH. Я полагаю, что это вызвано тем, что я не понимаю что [] действительно.

fmap :: (a -> b) -> f a -> f b  
  1. [], конструктор типа? Или, действительно ли это - конструктор значения?
  2. Что означает иметь тип: [] :: [a]?
  3. Похож на это Maybe конструктор типа, или Just конструктор значения?
    1. Если это похоже Just затем, каким образом Just имеет подпись как Just :: a -> Maybe a вместо Just :: Maybe a, другими словами, почему не [] введенный [] :: a -> [a]
  4. LYAH заявляет это, поскольку она относится к функторам: Заметьте, как мы не записали Функтор экземпляра где, потому что от fmap:: (-> b)-> f-> f b, мы видим, что f должен быть конструктором типа, который берет один тип. уже конкретного типа (списка с любым типом в нем), в то время как [] конструктор типа, который берет один тип и может произвести типы, такие как [Интервал], [Строка] или даже [[Строка]]. Я смущен хотя тип [] подразумевает, что это похоже на литерал для [a] что LYAH пытается достигнуть?

20
задан Fresheyeball 11 September 2014 в 16:34
поделиться

4 ответа

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

  2. Это означает, что (конструктор значения) [] имеет тип, который для всех типов a представляет собой список a (который записывается как [ а] ). Это потому, что у каждого типа есть пустой список.

  3. Конструктор значения [] не типизирован a -> [a] , потому что пустой список не имеет элементов, и поэтому ему не требуется a для создания пустой список из . Сравните с Ничего :: Может быть, вместо .

  4. LYAH говорит о конструкторе типа [] с видом * -> * , в отличие от конструктора значения [] с типом [a] .

15
ответ дан 29 November 2019 в 23:14
поделиться

Тип описывается (в сеансе GHCI) как:

$ ghci
Prelude> :info []
data [] a = [] | a : [a] -- Defined 

Мы также можем думать об этом так, как если бы он был определен как:

data List a = Nil
            | Cons a (List a)

или

data List a = EmptyList
            | ListElement a (List a)

Конструктор типов

[a] - это полиморфный тип данных, который также может быть записан [] a как указано выше. Это можно представить так, как будто это List a

В этом случае [] является конструктором типа , принимающим один аргумент типа a и возвращающим тип [] a , который также можно записать как [a] .

Можно написать такой тип функции:

sum :: (Num a) => [a] -> a

Конструктор данных

[] - это конструктор данных , что по сути означает «пустой список». Этот конструктор данных не принимает аргументов-значений.

Существует еще один конструктор данных, : , который добавляет элемент в начало другого списка. Подпись для этого конструктора данных a: [a] - он принимает элемент и другой список элементов и возвращает результирующий список элементов.

Обозначение [] также может использоваться как сокращение для построения списка.Обычно мы строим список как:

myNums = 3 : 2 : 4 : 7 : 12 : 8 : []

, который интерпретируется как

myNums = 3 : (2 : (4 : (7 : (12 : (8 : [])))))

, но Haskell позволяет нам также использовать сокращение

myNums = [ 3, 2, 4, 7, 12, 8 ]

как эквивалентное по значению, но немного более красивое по виду обозначение.

Неоднозначный случай

Часто встречается неоднозначный случай: [a] . В зависимости от контекста это обозначение может означать либо «список из a », либо «список с ровно одним элементом, а именно a ». Первое значение - это предполагаемое значение, когда [a] появляется внутри типа , тогда как второе значение является предполагаемым значением, когда [a] появляется внутри значение .

22
ответ дан 29 November 2019 в 23:14
поделиться
  1. это конструктор типов (например, [Int] - тип), и конструктор данных ([2] - структура списка).
  2. Пустой список - это список, содержащий любой тип
  3. [a] - как Maybe a, [2] - как Just 2.
  4. [] - нулевая функция (константа), поэтому не имеет типа функции.
9
ответ дан 29 November 2019 в 23:14
поделиться

Просто чтобы сделать вещи более явными, этот тип данных:

data List a = Cons a (List a) 
            | Nil

... имеет ту же структуру, что и встроенный тип списка, но без (более приятного, но потенциально запутанного) специального синтаксиса. Вот как выглядят некоторые соответствия:

  • List = [], конструкторы типов с видом * -> *
  • List a = [a], типы с видом *
  • Nil = [], значения с полиморфными типами List a и [a] соответственно
  • Cons = , конструкторы данных с типами a -> List a -> List a и a -> [a] -> [a] соответственно
  • Cons 5 Nil = [5] или 5:[], одноэлементные списки
  • f Nil = . .. = f [] = ... , сопоставление с образцом пустых списков
  • f (Cons x Nil) = ... = f [x] = ...`, шаблонное соответствие одноэлементных списков
  • f (Cons x xs) = ... = f (x:xs) = ... , pattern matching non-empty lists

На самом деле, если вы спросите ghci о [], он скажет вам практически такое же определение:

> :i []
data [] a = [] | a : [a]           -- Defined in GHC.Types

Но вы не можете написать такое определение сами, потому что синтаксис списка и его конструктор типа "outfix" - это особый случай, определенный в спецификации языка.

5
ответ дан 29 November 2019 в 23:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: