haskell - 在计算嵌套深度的方法中使用可重叠的捕获所有实例是否安全?

标签 haskell

考虑方法g:

class G a where
    g :: a -> Int

instance G a => G [a] where
    g [ ] = 1
    g xs = maximum (g <$> xs) + 1

instance G Void where
    g = absurd

 

λ g [[[]:: [Void]],[]]
3

它可以转换为适用于任何固定类型的嵌套列表,但我在使其多态时遇到困难。

如果我像这样定义一个包罗万象的实例:

instance G a where
    g _ = 0

− 它将与 G a => G [a] 重叠。我可以使用“重叠”和“可重叠”编译指示来允许这样做:

class G a where
    g :: a -> Int

instance {-# OVERLAPPABLE #-} G a => G [a] where
    g [ ] = 1
    g xs = maximum (g <$> xs) + 1

instance {-# OVERLAPPABLE #-} G a where
    g _ = 0

我尝试过一次类似的事情,got burned ,但我还是没有吸取教训。

我的问题:

  1. 如何确定此代码是否安全?
  2. 是否有更合适的方法来计算嵌套深度?

P.S. 我刚刚注意到我不小心为 G 的两个实例指定了“overlappable”。我一开始并没有注意到,因为它实际上似乎是这样工作的。如果说有什么不同的话,那就是让这个案子更加令人震惊。

最佳答案

我建议您使用数据而不是类。所以:

data FixedDepthTree a = Zero a | Succ (FixedDepthTree [a])

depth :: FixedDepthTree a -> Integer
depth (Zero _) = 0
depth (Succ t) = succ (depth t)

关于haskell - 在计算嵌套深度的方法中使用可重叠的捕获所有实例是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49335008/

相关文章:

haskell - 控制多类类型类中的类型应用顺序

oop - 函数式编程语言是如何工作的?

haskell - 如何编写一个可以序列化/反序列化来自类似 map 结构的任何记录的通用函数?

haskell - 使用模式查找第 n 个元素

haskell - 是否可以并行运行多个提示实例?

haskell - 在具有约束的方法中为 maxBound 类型推断错误

haskell - 如果不使用类型类约束,forall 的效用是什么?

使用 Maybe 的 Haskell 代码 zipWith

haskell - 为什么 sleep 不起作用?

scala - 用于文本编辑器的纯函数式数据结构