鉴于其主体功能,创建一个类型类的实例(或解决方法)
我想有一个国家Monad,我保留一个模式列表。
data State = S {
modes :: [Mode]
}
但是,我有两个要求:
以下是我试图说服GHC的方式:
尝试1 ,数据类型
data Mode a = Mode {
complF :: String -> IO [String]
action :: State -> String -> X a
}
data State a = S {
modes :: [Mode a]
}
initState :: (String -> IO [String]) -> (State -> String -> X a) -> State a
initState c a = {
modes = [buildMode c a]
}
buildMode :: (String -> IO [String]) -> (State -> String -> X a) -> Mode a
buildMode c a = {
complF = c
, action = a
}
好..但是,这对我来说没有用,因为每个模式都必须是State a
Mode a
State a
。 意思是没有Mode String
和Mode ()
可以在一个状态内共存。
尝试2:,输入类
class Mode a where
complF :: String -> IO [String]
action :: State -> String -> X a
data State = S {
modes :: (Mode a) => [a]
}
但是,现在我不知道如何在运行时为complF
和action
创建一个模式。 看来类型类的实例必须在编译时定义。
instance Mode DefaultMode where
complF :: ..
action :: ..
有没有解决方法?
如果模式支持固定API,则可以使用存在类型来隐藏其表示类型。 例如
data State = S {
modes :: forall a . ModeLike a => [Mode a]
}
然后实现一个仅具有Mode
类型支持的操作的ModeLike
类。 你的第二次尝试就是接近这个。
由于类型实例已打开,因此可以在不更改代码的情况下添加新实例。
但是,如果你有一个完全动态的系统 - 也就是说你不能枚举将成为可能模式的类型 - 你将不得不使用动态类型作为其中一个实例。
链接地址: http://www.djcxy.com/p/86097.html上一篇: Given its body functions, create an instance of a type class (or workaround)