2017-01-28 5 views
2

Haskell; x, y: целые числа.Haskell List Синтаксис с:

x : [y] : [] 

Что происходит в этом случае? Является [y] добавлен в [] или является x добавлен в [y]? Является результатом [x,[y]] или [[x,y]]?

Прошу прощения за плохой английский и благодарю вас за помощь.

+0

в '[[x, y]]' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' 'должны иметь одинаковый тип. Но в '[x, [y]]', 'x' должен быть того же типа, что и' [y] ', то есть список, с элементами того же типа, что и' y'. –

ответ

1

Посмотрите на тип

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

В словах: (:) принимает a и список a с и делает его список a с.

Таким образом, в x : [y] : [], вторая часть [y] : [] представляет собой список списков с элементами того же типа, что и y. Таким образом, x должен быть списком элементов, имеющих тот же тип, что и y. Например.

y = 1 
x = [2,3] 
list = x:[y]:[] 

и list является [[2,3],[1]].

Редактировать: Overread, что x и y должны быть целыми числами. Это, конечно, не сработает, см. Объяснение и попробуйте его в ghci.

+1

Если вы наберете ': i (:)' в ghci, вы можете узнать, что fixity ':' является infixr. Таким образом, если в соответствии с предположением OP, 'x' и' y' являются целыми числами, тогда выражение x: [y]: [] недостаточно хорошо напечатано ... Если вы, однако, оцениваете (x: [y]): [ ] результат будет [[x, y]]. –

+2

Этот тип не может использоваться для ответа на вопрос OP, который касается правил фиксации и синтаксического анализа. –

2

Вы можете спросить GHCI об информации неподвижности:

> :i : 
data [] a = ... | a : [a] -- Defined in ‘GHC.Types’ 
infixr 5 : 

Игнорирование первой линии на мгновение, вторая линия говорит infixr 5, что означает, что : правоассоциативным и имеет приоритет 5. «Ассоциированные к right "означает группу операторов" вправо ", поэтому e1 : e2 : e3 означает e1 : (e2 : e3).

Другие варианты включают infixl (группировка «влево») и infix (если вам потребуется группировка, сообщите об ошибке). Например, e1 + e2 + e3 означает (e1 + e2) + e3, потому что + является infixl:

> :i + 
class Num a where 
    (+) :: a -> a -> a 
    ... 
    -- Defined in ‘GHC.Num’ 
infixl 6 + 

И True == True == True ошибка синтаксического анализа, поскольку == является infix:

> :i == 
class Eq a where 
    (==) :: a -> a -> Bool 
    ... 
    -- Defined in ‘GHC.Classes’ 
infix 4 == 

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

Конечно, вы всегда можете использовать явные скобки для устранения неоднозначности или группировать операторы «по-другому»; например (e1 : e2) : e3 также является действительным выражением и означает что-то отличное от e1 : (e2 : e3), и (True == True) == True действителен и оценивается как True, хотя True == True == True недействителен.

Вот некоторые примеры, показывающие разницу:

> 1 : 2 : [3,4] 
[1,2,3,4] 
> 1 : (2 : [3,4]) 
[1,2,3,4] 
> (1 : [2]) : [[3,4],[5]] 
[[1,2],[3,4],[5]] 

Или, еще до точки:

> let e1 = []; e2 = ["ab","cd"]; e3 = [["ef","gh"],["ij"]] 
> e1 : e2 : e3 
[[],["ab","cd"],["ef","gh"],["ij"]] 
> e1 : (e2 : e3) 
[[],["ab","cd"],["ef","gh"],["ij"]] 
> (e1 : e2) : e3 
[["","ab","cd"],["ef","gh"],["ij"]] 

(Cooking до значений, которые делают оба из этих выражений хорошо типизированных было весело!)