使类成为另一个类的实例

pha*_*zon 7 haskell class instance

我有一个名为Foo拥有函数的类gen :: Int -> [Foo].例如,我可以用Foo这种方式制作一个实例:

data FooTest = FooTest Int

instance Foo FooTest where
  gen n = replicate n (FooTest 0)
Run Code Online (Sandbox Code Playgroud)

现在,让我们假设我有另一个叫做Bar定义函数的类bar :: Bar -> IO ().每个实例Foo都必须是实例Bar,Bar每个实例的实现完全相同.这是一个例子:

class Foo f where
  gen :: Int -> [f]

class Bar b where
  bar :: b -> IO ()

instance Bar Foo where -- obviously that doesn’t work
  bar _ = putStrLn "bar through any Foo instance"

instance (Foo f) => Bar f where -- this needs the FlexibleInstance GHC extension first, then it still throws shit saying that the constraint is not smaller that I don’t shit
  bar _ = putStrLn "bar through any Foo instance"
Run Code Online (Sandbox Code Playgroud)

这里的问题是我找不到任何方法使一个类成为另一个的实例,提到第一个类的任何实例将共享相同的实现来实例化另一个类.

任何的想法?

提前致谢.

Tik*_*vis 4

您可以使用带有两个扩展名的最后一个实例来完成您想要的任务:FlexibleInstancesUndecidableInstances

正如名称所暗示的那样,第二个扩展允许您编写不会终止的实例。这可能会导致编译时出现无限循环;然而,实现被任意限制在一定的递归深度,所以你实际上不应该有无限的编译时间。

我不知道有什么方法可以在没有任何扩展的情况下做到这一点。然而,使用扩展本质上并不是坏事,除非您将来可能想使用其他编译器。

另外,随机样式注释:如果只有一个约束,则括号是可选的。所以你可以把它写成:

instance Foo f => Bar f where ...
Run Code Online (Sandbox Code Playgroud)

这不是很重要,但我认为第二个版本看起来更好。