我的Haskell项目包括一个表达式求值程序,为了这个问题的目的可以简化为:
data Expression a where
I :: Int -> Expression Int
B :: Bool -> Expression Bool
Add :: Expression Int -> Expression Int -> Expression Int
Mul :: Expression Int -> Expression Int -> Expression Int
Eq :: Expression Int -> Expression Int -> Expression Bool
And :: Expression Bool -> Expression Bool -> Expression Bool
Or :: Expression Bool -> Expression Bool -> Expression Bool
If :: Expression Bool -> Expression a -> Expression a -> Expression a …Run Code Online (Sandbox Code Playgroud) AndrásKovács 在回答前一个问题时提出了这个问题.
在镜头风格的uniplate库中,* -> *基于类的类型
class Uniplate1 f where
uniplate1 :: Applicative m => f a -> (forall b. f b -> m (f b)) -> m (f a)
Run Code Online (Sandbox Code Playgroud)
类似于类的种类 *
class Uniplate on where
uniplate :: Applicative m => on -> (on -> m on) -> m on
Run Code Online (Sandbox Code Playgroud)
是有可能实现类似物contexts和holes,二者均具有类型Uniplate on => on -> [(on, on -> on)],而不需要Typeable1?
很明显,这可以在uniplate库的旧式中实现,该库用于Str通过返回具有子类型的类型级列表的结构来表示数据的结构.
一个洞可以用以下数据类型表示,它将替换(on, on -> on)为contexts …
{-# LANGUAGE RankNTypes #-}
Run Code Online (Sandbox Code Playgroud)
继续前一系列问题,我有一个带有通用量化函数作为参数的函数,如下所示:
emap :: (forall a. Expression a -> Expression a) -> Expression b -> Expression b
Run Code Online (Sandbox Code Playgroud)
对于不需要额外约束的函数,可以使用哪个,例如:
postmap :: (forall a. Expression a -> Expression a) -> Expression b -> Expression b
postmap f = f . emap (postmap f)
reduce = postmap step
Run Code Online (Sandbox Code Playgroud)
但是,我现在想要将此函数与带有附加约束的函数一起使用,但以下内容不进行类型检查.
substitute :: Pack a => Identifier -> a -> Expression a -> Expression a
substitute i v (Var x) | x == i = pack v
substitute _ _ …Run Code Online (Sandbox Code Playgroud)