Biorąc pod uwagę, na przykład, następujące dane rodzaj drzewa:Skoro "fałdowanie" nie jest wystarczająco mocne, aby napisać ładną drukarkę do drzewa z wcięciem, czym jest kombinator wyższego rzędu?
data Tree a = Node [Tree a] | Leaf a deriving Show
type Sexp = Tree String
Jak mogę wyrazić funkcję „Pretty” Używanie COMBINATOR wyższego rzędu, która drukuje drzewo z prawidłowego wcięcia? Na przykład:
sexp =
Node [
Leaf "aaa",
Leaf "bbb",
Node [
Leaf "ccc",
Leaf "ddd",
Node [
Leaf "eee",
Leaf "fff"],
Leaf "ggg",
Leaf "hhh"],
Leaf "jjj",
Leaf "kkk"]
pretty = ????
main = print $ pretty sexp
Chcę wynikiem tego programu będzie:
(aaa
bbb
(ccc
ddd
(eee
fff)
ggg
hhh)
jjj
kkk)
Oto niepełna rozwiązanie, za pomocą „spasować” jako Combinator, że nie realizuje wcięcia:
fold f g (Node children) = f (map (fold f g) children)
fold f g (Leaf terminal) = g terminal
pretty = fold (\ x -> "(" ++ (foldr1 ((++) . (++ " ")) x) ++ ")") show
main = putStrLn $ pretty sexp
to oczywiście nie jest możliwe, aby napisać funkcję chcę, używając fold
, ponieważ zapomina strukturę drzewa. Więc, co jest właściwym kombinatorem wyższego rzędu, który jest na tyle ogólny, że pozwala mi pisać funkcję, której chcę, ale mniejszą niż pisanie bezpośredniej funkcji rekursywnej?
Nie wiem, coś z monad? – bb94
Sądzę, że monady są zdecydowanie zbyt potężne, jak chcę. Oczywiście jest to możliwe z nimi, ale myślę, że coś mniej uniwersalnego może nadal to robić. Coś o fałdach z kontekstem ... Nie jestem pewien. – MaiaVictor
To zdecydowanie brzmi jak monady! – bb94