Каковы редексы в этом выражении Haskell?
Я изучаю Haskell для университетского курса, и у меня есть вопрос о приводимых выражениях (редексах). Я понимаю концепцию, но у меня все еще есть некоторые вопросы, которые я не могу решить самостоятельно.
Допустим, вы хотите найти все приводимые выражения в выражении, например:
head (map (+1) (3:repeat 3))
В этом выражении очевидным редексом будет
map (+1) (3:repeat 3))
потому что оно соответствует определению , поэтому Haskell «уменьшит» выражение и увеличит
3
а также
4:map (+1) (repeat 3)
. в следующий раз будет уменьшено.
У меня есть вопрос:
Является
head (map (+1) (3:repeat 3))
уже редекс, до
map
оценивается?
Поскольку «ввод» не соответствует конструктору списка (что и
head
ищет), я смущен тем, является ли это все еще редексом, потому что логически он еще не может быть сокращен, но определения в Интернете, кажется, говорят, что это будет.
1 ответ
Вычисление в Haskell ленивое: оно действует по стратегии самого верхнего левого редекса (по крайней мере, концептуально): он сокращает самый левый среди самых верхних редексов.
Предположительно определяется как
head xs = case xs of (x:_) -> x
таким образом, его применение к любому выражению действительно является редексом — выражением, нуждающимся в редукции. Что происходит в соответствии с определением ,
head (map (+1) (3:repeat 3))
=
case (map (+1) (3:repeat 3)) of (x:_) -> x
=
(или мы могли бы сказать, что
head
сам по себе является самым верхним крайним левым редексом, который сводится к его определению, во-первых; и если бы мы написали выше как
((\xs -> case xs of (x:_) -> x) (map (+1) (3:repeat 3)))
мы бы пришли к тому же результату, только немного более утомительно).
Основным принудительным примитивом является . Теперь ему нужно выполнить сопоставление с образцом, поэтому он должен узнать значение своего просматриваемого выражения (только в той степени, в которой совпадение с образцом становится возможным). Для этого он должен теперь работать в соответствии с определением
map
что предположительно
map f xs = case xs of { (x:ys) -> f x : map f ys
; [] -> [] }
так это становится
case (map (+1) (3:repeat 3)) of (x:_) -> x
=
case (case (3:repeat 3) of
{ (x:ys ) -> (+1) x : map (+1) ys
; [] -> [] } )
of (x:_) -> x
=
В этот момент внутреннее выражение может быть уменьшено,
case (let { x=3 ; ys=repeat 3} in
(+1) x : map (+1) ys )
of (x : _ ) -> x
=
а теперь внешний
case
сопоставление с образцом становится возможным,
case (let { x=3 } in
(+1) x )
of (x ) -> x
=
let { x=3 } in
(+1) x
=
(+1) 3
=
4