我目前有一个如下结构:
class F a where
f :: ...
default f :: (G a...) => ...
f = (some definition in terms of g)
class F a => G a where
g :: ...
default g :: (C a...) => ...
g = (some definition in terms of f)
Run Code Online (Sandbox Code Playgroud)
在希望有些简单的英语,我可以写f在以下方面g始终.我可以写g来讲f有时,即当a满足一个C约束.
我在这里看到的问题是,如果有人写作,比如说T满意的类型C T
instance F T
instance G T
Run Code Online (Sandbox Code Playgroud)
这将在运行时编译和循环.虽然两个默认定义都是正确的,但重要的是至少定义了一个.
我可以用一个MINIMALpragma 来解决这个问题,如果f并且g在同一个类中,但在这种情况下它们不是.
同时将两者f并g在同一个班似乎并不可能,因为同时存在的定义f为每一个定义g,没有的定义g为每一个定义f.一种可能性是g进入F但也对其施加C a约束,但这将阻止我g用任何a不满足的非默认定义来定义C a.
有没有办法重组这个来解决我面临的这种困境?
我之前的回答是无稽之谈,所以这里有一个(希望)更好的答案。这至少会在编译时给你一个警告。技巧是如果两者都有和 的实例,则在类中实现f'或,但前提是的实例不可能。gGaFGfG
{-# LANGUAGE DefaultSignatures #-}
class C a where
class F a where
f :: a -> a
default f :: (G a) => a -> a
f = g
class F a => G a where
{-# MINIMAL (f'|g) #-}
f' :: a -> a
f' = f
g :: a -> a
default g :: (C a) => a -> a
g = f'
instance F Integer where
f = succ
instance F Int
instance G Int where
g = succ
instance C Float
instance F Float
instance G Float where
f' = succ
-- This will give a compile time warning, but will still
-- loop at runtime:
instance C Double
instance F Double
instance G Double
Run Code Online (Sandbox Code Playgroud)