После прочтения (и реализации) части http://blog.sumtypeofway.com/recursion-schemes-part-2/ Мне все еще интересно, как работают функции в функции cata
. cata
функция определяется следующим образом:Haskell cata types
mystery :: Functor f => (f a -> a) -> Term f -> a
mystery f = f . fmap (mystery f) . unTerm
У меня есть что-то вроде Term Expr
. После распаковки я получаю Expr (Term Expr)
. Алгебра (f
) определена, например, как f :: Expr Int -> Int
. Я знаю, что я мог бы назвать следующие легко:
x = Literal "literal" :: Expr a
f :: Expr Int -> Int
f x :: Int
Я также могу представить себе:
x = Literal "literal" :: Expr (Term Expr)
f :: Expr a -> Int
f x :: Int
Но следующий, я полагаю, не будет работать:
x = Literal "literal" :: Expr (Term Expr)
f :: Expr Int -> Int
f x :: ???
Однако, я до сих пор дон Как это работает в функции cata
- как мне добраться от Expr (Term Expr)
до Expr a
. Я понимаю, что значения действительно работают, но я просто не получаю типы - что происходит в листьях дерева? Это действительно mystery
...
Редактировать: Я постараюсь более четко указать, что я не понимаю.
Мысленно, то cata
, кажется, работает так:
- Применить
fmap f
листьям. - Теперь у меня есть
Expr Int
, и я могу позвонитьfmap f
на узел, который у меня есть, и встать.
Это не работает так, как я применяю fmap (cata f)
. Однако в конечном счете функция f
вызывается с Expr Int
в качестве аргумента (в листьях). Как этот тип был произведен с Expr (Term Expr)
, что он был раньше?
Вы не можете определить значащий 'f :: Expr a -> Int'. – chi
Уверен, что вы можете: 'f (Literal str) = length str' – ondra
кажется, что ваш' f' больше не является полной функцией ... как насчет 'f (Paren ...)'? – Carsten