在实施细化类型系统时,我需要进行检查以确保类型格式正确。例如,类似Num[100,0]
的类型不应该发生,其中Num[lb,ub]
是大于lb
且小于ub
的数字类型。然后我写道:
-- FORMATION RULES
class RefTy t
where tyOK :: t -> Bool
instance RefTy Ty
where tyOK (NumTy (n1, n2)) = n1 <= n2
tyOK (CatTy cs) = isSet cs
{-
data WellFormed t = Valid t
| Invalid
instance Monad WellFormed
where
(>>=) :: RefTy a => WellFormed a -> (a -> WellFormed b) -> WellFormed b
Valid t >>= f
| tyOK t = f t
| otherwise = Invalid
Invalid >>= _ = Invalid
-}
让我了解&#34; restricted Monad&#34;的已知问题。建议的答案是让Wellformed
monad为通用但限制函数。然而,这将回到在任何地方添加格式良好的检查。有没有更好的出行方式?
答案 0 :(得分:4)
在你的情况下,我不认为你真的想要一个monad,只是伴随do
符号的糖。例如,您是否考虑过您对Applicative
的定义是什么样的?当你试图欺骗时,事情变得很乱。
相反,如果你想使用do
- 表示法,我建议你使用
{-# LANGUAGE RebindableSyntax #-}
允许您重新定义用于消除(>>=)
块的return
和do
等内容。然后你可以写下这样的东西:
myBind :: RefTy t1 => WellFormed t1 -> (t1 -> WellFormed t2) -> WellFormed t2
myBind Invalid _ = Invalid
myBind (Valid t) f | tyOK t = f t
| otherwise Invalid
myReturn :: WellFormed t
myReturn t = Valid t
我不确定我是否同意这些定义,但无论你怎么能写出类似
的内容do
...
where (>>=) = myBind
return = myReturn