gpt4 book ai didi

haskell - Church-encoded 列表的 Catamorphisms

转载 作者:行者123 更新时间:2023-12-04 19:57:54 26 4
gpt4 key购买 nike

我希望能够使用 cata来自 recursion-schemes Church 编码列表的包。

type ListC a = forall b. (a -> b -> b) -> b -> b

为方便起见,我使用了二级类型,但我不在乎。随意添加 newtype ,如果您觉得有必要,请使用 GADTs 等。

Church 编码的思想广为人知且简单:
three :: a -> a -> a -> List1 a 
three a b c = \cons nil -> cons a $ cons b $ cons c nil

基本上是“未指定的抽象” consnil用于代替“普通”构造函数。我相信一切都可以用这种方式编码( Maybe 、树等)。

很容易证明 List1确实与普通列表同构:
toList :: List1 a -> [a]
toList f = f (:) []

fromList :: [a] -> List1 a
fromList l = \cons nil -> foldr cons nil l

所以它的基函数和列表一样,应该可以实现 project并使用来自 recursion-schemes 的机器.

但我不能,所以我的问题是“我该怎么做?”。对于普通列表,我可以只进行模式匹配:
decons :: [a] -> ListF a [a]
decons [] = Nil
decons (x:xs) = Cons x xs

由于我无法对函数进行模式匹配,因此我必须使用折叠来解构列表。我可以写一个基于折叠的 project对于普通列表:
decons2 :: [a] -> ListF a [a]
decons2 = foldr f Nil
where f h Nil = Cons h []
f h (Cons hh t) = Cons h $ hh : t

但是,我未能将其调整为 Church-encoded 列表:
-- decons3 :: ListC a -> ListF a (ListC a)
decons3 ff = ff f Nil
where f h Nil = Cons h $ \cons nil -> nil
f h (Cons hh t) = Cons h $ \cons nil -> cons hh (t cons nil)
cata具有以下签名:
cata :: Recursive t => (Base t a -> a) -> t -> a

要将它与我的列表一起使用,我需要:
  • 使用 type family instance Base (ListC a) = ListF a 声明列表的基本仿函数类型
  • 实现 instance Recursive (List a) where project = ...

  • 我两步都失败了。

    最佳答案

    newtype包装器原来是我错过的关键步骤。这是来自 recursion-schemes 的代码以及示例 catamorphism .

    {-# LANGUAGE LambdaCase, Rank2Types, TypeFamilies #-}

    import Data.Functor.Foldable

    newtype ListC a = ListC { foldListC :: forall b. (a -> b -> b) -> b -> b }

    type instance Base (ListC a) = ListF a

    cons :: a -> ListC a -> ListC a
    cons x (ListC xs) = ListC $ \cons' nil' -> x `cons'` xs cons' nil'
    nil :: ListC a
    nil = ListC $ \cons' nil' -> nil'

    toList :: ListC a -> [a]
    toList f = foldListC f (:) []
    fromList :: [a] -> ListC a
    fromList l = foldr cons nil l

    instance Recursive (ListC a) where
    project xs = foldListC xs f Nil
    where f x Nil = Cons x nil
    f x (Cons tx xs) = Cons x $ tx `cons` xs

    len = cata $ \case Nil -> 0
    Cons _ l -> l + 1

    关于haskell - Church-encoded 列表的 Catamorphisms,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31464976/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com