В Haskell нет переменных, а только значения, привязанные к именам.
Какого список понимание, как это будет заводится в самом деле монадический Список коды:
y = [x + 1 | x <- [1, 2, 3, 4, 5]]
y = do
x <- [1, 2, 3, 4, 5]
return (x + 1)
Тогда это дополнительно получает уменьшенные к использованию >>=
:
y = [1, 2, 3, 4, 5] >>= (\x -> return (x + 1))
И тогда мы можем смотреть на определение для примера Monad
для []
:
instance Monad [] where
return x = [x]
list >>= f = concat (map f list)
-- uses the `concatMap` function in the actual definition
-- where `concatMap f list = concat (map f list)`
Так замена return
:
y = [1, 2, 3, 4, 5] >>= (\x -> [x + 1])
А потом >>=
:
y = concat (map (\x -> [x + 1]) [1, 2, 3, 4, 5])
Теперь мы можем уменьшить его:
y = concat [[1 + 1], [2 + 1], [3 + 1], [4 + 1], [5 + 1]]
y = concat [[2], [3], [4], [5], [6]]
y = [2, 3, 4, 5, 6]
Так как вы можете видеть, это не значит, что x
переменная который изменяет значения, x
становится аргументом функции лямбда, которая затем отображается на ta rget list.
Отличный ответ, но два nitpicks: (a) «значения, связанные с именами» - это то, что переменные находятся в математике; говоря, что у Haskell нет переменных, я думаю, может только создать путаницу; (б), насколько я понимаю, компилятор фактически не превращает списки в монадический код; в основном, он пропускает шаги в вашем ответе, которые включают 'do',' >> = 'и' return'. Это полностью эквивалентно тому, что вы показываете. –
@ LuisCasillas Это ручная волна, конечно. Что GHC на самом деле desugar это, это настраиваемая функция 'map'' f = \ ys -> case ys {[] -> []; (x: xs) -> (x + 1): f xs', затем примените это к '[1, 2, 3, 4, 5]', но базовое понятие одинаков. Я предполагаю, что там есть некоторые оптимизации для простых случаев, подобных этому, но в целом я считаю справедливым сказать, что GHC делает такого рода обезжиривание, даже если он не делает этого точного вида desugaring. – bheklilr
@ LuisCasillas И я думаю, что правильно сказать, что у Haskell нет переменных в том смысле, что у Python есть переменные. Люди всегда вызывают 'IORef' и т. П., Но они все еще не являются переменными, чтобы получить значение от них или в них, вы выполняете операцию ввода-вывода, вы фактически не изменяете саму ссылку. Как только имя связано в Haskell, вы не сможете повторно связать его позже. Это имя может принимать разные значения в разных контекстах, но оно не изменяет и поэтому не меняется и не может удовлетворить основное требование быть переменной. – bheklilr