【问题标题】:Repetitions as an Hylomorphism重复作为一个类同态
【发布时间】:2018-06-13 18:08:28
【问题描述】:

所以我一直在尝试将这个检查列表是否没有任何重复的 Haskell 函数转换为 Hylomorphism,但它有些奇怪。

valid :: [a] -> Bool
valid [] = True
valid (h:t) = if (not (elem h t)) then valid t else False  

如果有人可以提供帮助,我会很高兴!谢谢

【问题讨论】:

  • 这有什么奇怪的?
  • 我的想法是检查头部是否在尾部,例如 aux(a,t) => 检查 a 是否出现在 t 中,但是当我尝试这样做时,显然我正在构建布尔列表
  • 你错了,函数按照你说的做。

标签: haskell recursion-schemes catamorphism anamorphism


【解决方案1】:

hylomoprhism 是一个函数 h : A → C 可以定义为变形(gp)和变质(c) >) 部分。

变形部分包含一个函数 g : A → B × A 将对象“展开”成更小的部分,而 p : A → Bool 一个判断我们是否完成展开的谓词。

catamorphism 部分包含一个值 c ∈ C 和一个运算符 ⊕ : B × C → C.

(本文为Wikipedia page的略微修改版)

在您的情况下,unfolding 意味着我们以某个值(B 类型和 recursive 部分)展开列表,即这里是列表的tail

谓词 p 可以从您的定义中派生出来:如果列表为空,则我们已经终止。很明显,在这种情况下我们返回True,这意味着cTrue

那么现在 B 部分会是什么?好吧,如果我们查看您的函数,我们需要访问列表的 headtail,因此 B 可以看作是 2 - 包含头部(作为第一个元素)和尾部(作为第二个元素)的元组。

那么现在剩下的问题是 做了什么?它将一个 E×[E] 类型的 2 元组(伪 Haskell 表示法)和一个布尔值(类型为 CBool)作为输入。正如我们所看到的,它检查头部是否是尾部的元素。如果是则返回False,并忽略递归部分,否则返回递归部分。

所以我们可以在 Haskell 中这样写:

-- types
type A e = [e]
type B e = (e, [e])
type C = Bool

-- functions
p :: A e -> Bool
p [] = True
p (_:_) = False

g :: A e -> (B e, A e)
g (h:t) = ((h, t), t)

c :: C
c = True

plus :: Eq e => B e -> C -> C
plus (h, t) r | elem h t = False
              | otherwise = r

hylo :: Eq e => A e -> C
hylo a | p a = c
       | otherwise = plus b (hylo a')
    where (b, a') = g a

hylo 因此是一个基于定义的简单实现,我们将函数 pcplusg 作为“构建块”。

【讨论】:

    猜你喜欢
    • 2020-08-31
    • 1970-01-01
    • 2011-03-06
    • 1970-01-01
    • 1970-01-01
    • 2014-03-08
    • 1970-01-01
    • 2020-10-27
    • 1970-01-01
    相关资源
    最近更新 更多