й Рассказывается concatMap
работы, поэтому я остановлюсь именно на одном из ваших сомнений:
Но как мы можем установить функцию, равную другой?
Функция в Haskell - это значение, как и любое другое.
GHCi> foo = "foo"
Это определение foo
, который бывает строка:
GHCi> :t foo
foo :: [Char]
GHCi> putStrLn foo
foo
Таким же образом ...
GHCi> add = (+)
... это определение add
, который является функцией:
GHCi> :t add
add :: Num a => a -> a -> a
GHCi> add 2 3
5
В приведенном выше определении, чтобы подчеркнуть, что я просто определял значение, я не написал ни одного из параметров add
явно. Это прекрасно, чтобы сделать это, хотя:
GHCi> add x y = (+) x y
(. Обратите внимание, что x + y
, который, как мы обычно бы написать правую из приведенного выше определения, просто удобно альтернативный синтаксис для (+) x y
)
Другой способ написания определение имеет преимущество частичного применения упомянуть только первый параметр:
GHCi> add x = (+) x
Мы также можем, только для ради этого (и, возможно, выяснить, что происходит), переместите (+) x
в отдельное определение в где-п ...
GHCi> :{
GHCi| add x = plusX
GHCi| where
GHCi| plusX = (+) x
GHCi| :}
... и записать второй параметр явно снова:
GHCi> :{
GHCi| add x = plusX
GHCi| where
GHCi| plusX y = (+) x y
GHCi| :}
plusX
- это функция, которая принимает аргумент и добавляет его в x
. add
- это функция, которая принимает аргумент x
и возвращает функцию plusX
, соответствующую этому x
. Именно эта вторая функция принимает второй аргумент add
, когда мы делаем add 2 3
(что, кстати, эквивалентно (add 2) 3
).
Теперь сравните выше с concatMap
определения:
concatMap f = cmap where
cmap [] = []
cmap (x : xs) = accum (f x) where
accum [] = cmap xs
accum (y : ys) = y : accum ys
Определения изложены аналогичным образом. cmap
- это функция, которая принимает список и использует f
, аргумент concatMap
, чтобы получить результат от него, точно так же plusX
использовал аргумент x
add
.
Итак, подведем итог:
настраиваете мы результат е равно CMAP, или мы используем CMap в качестве параметра для е?
Ни то, ни другое. Мы используем f
для определения cmap
, который затем используется для определения concatMap
в целом.
Этот код написан как точка-иш, который не очень дружелюбен к новичкам.Добавьте 'ys' с обеих сторон' = ', и это может стать проще, например. 'concatMap f ys = cmap ys'. Кроме того, каноническое определение 'concatMap f' является' concat. карта f'. – Zeta
Я бы, наверное, пошел немного дальше и сказал, что код запутан. Я не вижу веских оснований писать странную функцию 'accum' вместо того, чтобы просто использовать' cmap (x: xs) = f x ++ cmap xs'. – dfeuer