Существует ли расширитель уравнения для Haskell?
Что-то вроде foldr.com: 1+(1+(1+(1+(…))))=∞
Я новичок в Haskell. Мне трудно понять, почему некоторые уравнения более предпочтительны, чем другие. Я думаю, что это помогло бы, если бы я мог видеть, как уравнения расширяются.
Например, я обнаружил, что foldr
vs foldl
трудно понять сначала, пока я не увидел, что они расширены.
foldr :: (a -> b -> b) -> b -> [a] -> b
foldr k z xs = go xs
where
go [] = z
go (y:ys) = y `k` go ys
foldl :: (a -> b -> a) -> a -> [b] -> a
foldl f z0 xs0 = lgo z0 xs0
where
lgo z [] = z
lgo z (x:xs) = lgo (f z x) xs
Из определений видно, что foldr
расширяется следующим образом:
foldr (+) 0 [1..1000000] -->
1 + (foldr (+) 0 [2..1000000]) -->
1 + (2 + (foldr (+) 0 [3..1000000])) -->
1 + (2 + (3 + (foldr (+) 0 [4..1000000]))) -->
1 + (2 + (3 + (4 + (foldr (+) 0 [5..1000000])))) -->
и foldl
расширяется следующим образом:
foldl (+) 0 [1..1000000] -->
foldl (+) (foldl (+) 0 [1]) [2..1000000]) -->
foldl (+) (foldl (+) (foldl (+) 0 [1])) [3..1000000]) -->
или из Haskell Wiki в foldr fold foldl:
let z1 = 0 + 1
in foldl (+) z1 [2..1000000] -->
let z1 = 0 + 1
z2 = z1 + 2
in foldl (+) z2 [3..1000000] -->
let z1 = 0 + 1
z2 = z1 + 2
z3 = z2 + 3
in foldl (+) z3 [4..1000000] -->
let z1 = 0 + 1
z2 = z1 + 2
z3 = z2 + 3
z4 = z3 + 4
in foldl (+) z4 [5..1000000] -->
Однако у меня проблемы с более крупными уравнениями, понимающими, почему все работает так, как они делают в Haskell. Например, первая ситовая функция использует 1000 фильтров, тогда как вторая ситовая функция принимает только 24, чтобы найти 1001 prime.
primes = sieve [2..]
where
sieve (p:xs) = p : sieve [x | x <- xs, rem x p /= 0]
primes = 2: 3: sieve (tail primes) [5,7..]
where
sieve (p:ps) xs = h ++ sieve ps [x | x <- t, rem x p /= 0]
-- or: filter ((/=0).(`rem`p)) t
where (h,~(_:t)) = span (< p*p) xs
Я потратил хорошее время на разработку и расширение вручную. Я понял, как это работает. Однако автоматизированный инструмент для расширения определенных выражений значительно улучшил бы мое понимание Haskell.
Кроме того, я думаю, что это могло бы также помочь в вопросах, которые направлены на оптимизацию кода Haskell:
- Оптимизация кода Haskell
- Помогите оптимизировать мой код haskell. Вычислите сумму всех простых чисел ниже двух миллионов.
Есть ли инструмент для расширения выражений Haskell?