Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Design patterns 非二叉树与复合设计模式的类同构的初学者实现_Design Patterns_Haskell_Composite_Catamorphism - Fatal编程技术网

Design patterns 非二叉树与复合设计模式的类同构的初学者实现

Design patterns 非二叉树与复合设计模式的类同构的初学者实现,design-patterns,haskell,composite,catamorphism,Design Patterns,Haskell,Composite,Catamorphism,就目前而言,梦想还在继续,在哈斯凯尔的每一个概念中,我都被吸引住了。 然而,我还没有完全完成这个宝贵的@luqui的答案,我会回来,直到它的好。这是关于维基百科上的示例代码,处理的是 尽管如此,我还是尝试对非二叉树实现了自同构,但我遇到了一些问题: data Composition a = Leaf a | Composite [Composition a] data CompositionAlgebra a r = CompositionAlgebra

就目前而言,梦想还在继续,在哈斯凯尔的每一个概念中,我都被吸引住了。 然而,我还没有完全完成这个宝贵的@luqui的答案,我会回来,直到它的好。这是关于维基百科上的示例代码,处理的是

尽管如此,我还是尝试对非二叉树实现了自同构,但我遇到了一些问题:

data Composition a = Leaf a
                   | Composite [Composition a]

data CompositionAlgebra a r = CompositionAlgebra { leaf      :: a →  r
                                                 , composite :: [r] →  r }

foldComposition :: CompositionAlgebra a r →  Composition a →  r
foldComposition a@(CompositionAlgebra {leaf   = f}) (Leaf   x  ) = f x
foldComposition a@(CompositionAlgebra {composite = g}) (Composite [y]) =  map g [y] 
-地图g[y]上最新的那条线不符合ghc的要求

maxOfPair :: a →  a →  a
maxOfPair x y = if( x > y) -- this doesnt please ghc either, Ordering trouble
                then (x) 
                else (y)

maxInList :: [a] →  a
maxInList (x:xs) = maxOfPair x (maxInList xs)

treeDepth :: CompositionAlgebra a Integer
treeDepth = CompositionAlgebra { leaf = const 1, composite = λx →  1 + maxInList x }

sumTree :: (Num a) ⇒ CompositionAlgebra a a
sumTree = CompositionAlgebra { leaf = id, composite = (+) } 
-对于ghc来说,这棵最迟的树也是错误的

<>我看到>和+,就像C++运算符>和+一样。因此,我不明白ghc在没有我的帮助下会对我生气,不管我是不是执行了Operator>/+操作

第二,我必须承认我对=>与->的区别完全不清楚???和@似乎是模式匹配的指南

如何更正此代码

还有一个最新的问题, 我也尝试这样做,因为复合模式恰好是我在C++中最重要的。很明显,在哈斯克尔的书中,只有一两行文字可以描述这一点,这对我来说真是太神奇了

但是,haskell的人如何表达这样一个事实:组合的Leaf和Composite构造函数可能具有某种相同的接口?我知道这不是一个好词,因为数据是不可变的,但我希望你能猜出我的担忧/目标

这是全部编译错误

src\Main.hs:27:79:
    Couldn't match expected type `[r]'
           against inferred type `Composition a'
    In the expression: y
    In the second argument of `map', namely `[y]'
    In the expression: map g [y]

src\Main.hs:30:20:
    Could not deduce (Ord a) from the context ()
      arising from a use of `>' at src\Main.hs:30:20-24
    Possible fix:
      add (Ord a) to the context of the type signature for `maxOfPair'
    In the expression: (x > y)
    In the expression: if (x > y) then (x) else (y)
    In the definition of `maxOfPair':
        maxOfPair x y = if (x > y) then (x) else (y)

src\Main.hs:41:0:
    Occurs check: cannot construct the infinite type: a = [a] -> [a]
    When generalising the type(s) for `sumTree'
编辑 这是非二元亚同态的最终版本

data Composant a = Leaf a
                 | Composite [Composant a]

data CompositionAlgebra a r = CompositionAlgebra { leaf      :: a →  r
                                             , composite :: [r] →  r }

foldComposition :: CompositionAlgebra a r →  Composant a →  r
foldComposition a@(CompositionAlgebra {leaf = f}) (Leaf x) = f x
foldComposition a@(CompositionAlgebra {composite = g}) (Composite ys) =  g(map(foldComposition a) ys)

maxOfPair :: Ord a ⇒ a →  a →  a
maxOfPair x y = if( x > y) 
                then (x) 
                else (y)

maxInList :: Ord a => [a] →  a
maxInList (x:xs) = maxOfPair x (maxInList xs)

treeDepth :: CompositionAlgebra a Integer
treeDepth = CompositionAlgebra { leaf = const 1, composite = λx →  1 + maxInList x }

addList :: Num a ⇒ [a] → a
addList (x:xs) = x + addList xs 

sumTree :: (Num a) ⇒ CompositionAlgebra a a
sumTree = CompositionAlgebra { leaf = id, composite = addList } 

并根据下面的有效答案:我所要求的Haskell等价的C++接口契约似乎是类型约束。


因此,设计模式组合将通过在构造组合a时应用类型类约束来实现。也许应该定义一个新的专用数据。但是我应该先学习TypeClass,然后再做:-

这里有一些不同的错误,所以我不确定处理这些错误的最佳方法,但到底是什么

将来,尝试包含GHC提供的更多错误

在:

我可以看到foldCompose函数有两个错误,类型检查器只会捕获其中一个错误

您正在复合[y]上进行模式匹配,它将只匹配一个元素的列表。您可能需要复合ys,它将ys绑定到整个列表

map g[y]不会通过类型检查器,因为您已经将g定义为接受r的列表,但是您给了它一个a的列表

为了将a转换为r,您需要对其应用合成文胸:g映射折叠合成a ys

因此,我将这样写:

foldComposition :: CompositionAlgebra a r →  Composition a →  r
foldComposition a@(CompositionAlgebra {leaf   = f}) (Leaf   x  ) = f x
foldComposition a@(CompositionAlgebra {composite = g}) (Composite ys) = g (map (foldComposition a) ys)
对于下一个错误:

maxOfPair :: a →  a →  a
maxOfPair x y = if( x > y) -- this doesnt please ghc either, Ordering trouble
                then (x) 
                else (y)
在Haskell中,调用方可以根据自己的选择,使用任何类型来填充类型变量,如a here all by it lonesome

这意味着您在类型签名中声明函数maxPair将适用于每种输入类型。GHC以自己的方式抱怨操作符>不适用于每种类型,因此拒绝编译您的程序

您需要使用TypeClass来解决此问题。在Haskell中,类型类允许调用者选择要使用的类型,但有一些限制。我建议你读一本哈斯克尔的书

正确的类型签名应为:

maxOfPair :: Ord a => a →  a →  a
将Ord约束应用于类型a


另外,您应该使用标准函数。

这里有一些不同的错误,因此我不确定在这样的情况下处理它的最佳方法,但究竟是什么

将来,尝试包含GHC提供的更多错误

在:

我可以看到foldCompose函数有两个错误,类型检查器只会捕获其中一个错误

您正在复合[y]上进行模式匹配,它将只匹配一个元素的列表。您可能需要复合ys,它将ys绑定到整个列表

map g[y]不会通过类型检查器,因为您已经将g定义为接受r的列表,但是您给了它一个a的列表

为了将a转换为r,您需要对其应用合成文胸:g映射折叠合成a ys

因此,我将这样写:

foldComposition :: CompositionAlgebra a r →  Composition a →  r
foldComposition a@(CompositionAlgebra {leaf   = f}) (Leaf   x  ) = f x
foldComposition a@(CompositionAlgebra {composite = g}) (Composite ys) = g (map (foldComposition a) ys)
对于下一个错误:

maxOfPair :: a →  a →  a
maxOfPair x y = if( x > y) -- this doesnt please ghc either, Ordering trouble
                then (x) 
                else (y)
在Haskell中,调用方可以根据自己的选择,使用任何类型来填充类型变量,如a here all by it lonesome

这意味着您在类型签名中声明函数maxPair将适用于每种输入类型。GHC以自己的方式抱怨操作符>不适用于每种类型,因此拒绝编译您的程序

您需要使用TypeClass来解决此问题。在Haskell中,类型类允许调用者选择要使用的类型,但有一些限制。我建议你读一本哈斯克尔的书

正确的类型签名应为:

maxOfPair :: Ord a => a →  a →  a
将Ord约束应用于类型a

另外,您应该使用标准函数

老实说,我必须承认我完全错了 模糊的感觉=>不同 从->开始???和@似乎是 就像模式匹配的指南

考虑函数,该函数测试列表是否包含某个值。你可以把它定义为

elem _ [] = False
elem x (y:ys) | x == y = True
              | otherwise = elem x ys
哪个签名具有此功能?看起来像elem::a->[a]->Bool。但是编译器会抱怨,因为您编写了x==y,并且并不是为每个a定义了==函数,而是只为中的a定义了==函数。所以你需要为等式中的所有a指定类似的东西。。。。正是为了这个,你需要=>。因此elem的正确签名是elem::Eq a=>a->[a]->Bool

@使您可以为整个结构命名,同时在其上进行模式匹配。例如,如果你有这个图案a@x:xs用[1,2,3,4]调用该函数,那么a是[1,2,3,4],xis1和xs是[2,3,4]

第二,我必须承认我完全错了 模糊的感觉=>不同 从->开始???和@似乎是 就像模式匹配的指南

考虑函数,该函数测试列表是否包含某个值。你可以把它定义为

elem _ [] = False
elem x (y:ys) | x == y = True
              | otherwise = elem x ys
哪个签名具有此功能?看起来像elem::a->[a]->Bool。但是编译器会抱怨,因为您编写了x==y,并且并不是为每个a定义了==函数,而是只为中的a定义了==函数。所以你需要为等式中的所有a指定类似的东西。。。。正是为了这个,你需要=>。因此elem的正确签名是elem::Eq a=>a->[a]->Bool


@使您可以为整个结构命名,同时在其上进行模式匹配。例如,如果你有这个图案a@x:xs用[1,2,3,4]调用该函数,那么a是[1,2,3,4],xis1和xs是[2,3,4]。

Thanx Antoine。抱歉,如果我的帖子太长,但与你认为的相反,整个ghc的错误报告被引用在我的答案的底部。你花时间纠正我,真是太好了,我现在就去做。很高兴我能帮上忙!我希望我的回答不是太严厉——有时我发现很难找到正确的语气。不,别担心,我也不喜欢当编译错误没有出现在问题帖子中时;-。你指给我看的有趣的教程又是一个thanx。它在演示中非常轻量级,但我可以非常快速地投入其中,并专注于我感兴趣的要点。今天下午我要攻击IO和monads。我不耐烦了!安托万。抱歉,如果我的帖子太长,但与你认为的相反,整个ghc的错误报告被引用在我的答案的底部。你花时间纠正我,真是太好了,我现在就去做。很高兴我能帮上忙!我希望我的回答不是太严厉——有时我发现很难找到正确的语气。不,别担心,我也不喜欢当编译错误没有出现在问题帖子中时;-。你指给我看的有趣的教程又是一个thanx。它在演示中非常轻量级,但我可以非常快速地投入其中,并专注于我感兴趣的要点。今天下午我要攻击IO和monads。我不耐烦了!谢谢。现在我的口袋里有了=>和@;-。很好。所以,这意味着第一个a@是无用的,因为它不在该定义中使用。@Stephane:是的,你不需要它。Thx。现在我的口袋里有了=>和@;-。很好。这意味着第一个a@是无用的,因为它没有在那个定义中使用。@Stephane:是的,你不需要它。