我试图创建一个系统,允许将具有未知类型的列表数据应用于可能失败的函数。
数据和功能必须属于同一类型。例如,数据存储如下:
data Data = DInt Int | DBool Bool ...
虽然这些功能在经过一些讨论后会是类型:
[Data] -> Either Error Data
我在一周前发布了一个类似的question,经过一些调整,我设法使用类型类为函数制作了一个粗略但可行的解决方案。我遇到的问题是我的代码适用于非多态函数,例如
Int -> Bool -> Int
但它不能处理这样的事情:
a -> b -> a
我已经开始工作的样本如下。
{-# LANGUAGE FlexibleInstances, UndecidableInstances#-}
data Data = DInt Int | DBool Bool
data Error = TypeError String Data | MissingArg | ExtraArgs
class Arg a where
getArg :: Data -> Either Error a
wrap :: a -> Data
instance Arg Int where
getArg (DInt x) = Right x
getArg x = Left $ TypeError "DInt" x
wrap x = DInt x
instance Arg Bool where
getArg (DBool x) = Right x
getArg x = Left $ TypeError "DBool" x
wrap x = DBool x
class Function a where
exec :: a -> [Data] -> Either Error Data
instance Arg a => Function a where
exec x [] = Right (wrap x)
exec _ _ = Left ExtraArgs
instance {-# OVERLAPPING #-} (Function f, Arg a) => Function (a -> f) where
exec f (x:xs) = do
x' <- getArg x
exec (f x') xs
exec _ [] = Left $ MissingArg
我可以创建一个用于处理多态类型的Arg类型类型,还是有另一种方法可以实现更适合的行为? 谢谢,如果您对此问题有任何澄清,请告诉我们?