我正在尝试归纳地定义一对类实例。那就是:
class Foo a b | a -> b where
foo :: a -> b
instance (not?)Foo a => Bar a b
foo x = ...
instance Foo a => Bar a b
foo x = ...
第一个实例确定基本操作,秒递归调用foo。有没有办法做到这一点?一个很好的例子是扁平化列表,其中第一种情况是标识函数,第二种情况是concat的递归应用。
答案 0 :(得分:8)
由于一个非常简单的原因,无法直接执行此操作 - 实例选择仅查看“头部”,即=>
之后的部分。您在上下文中放置的任何内容 - =>
之前的部分 - 都可以影响选择的实例。
对于简单的情况,您通常可以完全避免这个问题,例如是否存在数量有限的“基本案例”类型。一个常见的例子是类型级别列表,其中您有Cons
的递归案例和Nil
的基本案例,就是这样。
在一般情况下,您通常需要某种“条件测试”类型类,根据是否满足某些条件来选择类型,然后将实际实现交给“辅助”类,该类采用条件结果值作为参数并使用它来选择实例。
答案 1 :(得分:5)
这是一个implementation of a flatten function,适用于任何级别的嵌套列表。我不会真的推荐使用它 - 这里只是为了演示如何在haskell中实现这样的东西。