使用monad隐式检查细化类型是否良好

时间:2016-07-25 16:16:56

标签: haskell dependent-type refinement-type

在实施细化类型系统时,我需要进行检查以确保类型格式正确。例如,类似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为通用但限制函数。然而,这将回到在任何地方添加格式良好的检查。有没有更好的出行方式?

1 个答案:

答案 0 :(得分:4)

在你的情况下,我不认为你真的想要一个monad,只是伴随do符号的糖。例如,您是否考虑过您对Applicative的定义是什么样的?当你试图欺骗时,事情变得很乱。

相反,如果你想使用do - 表示法,我建议你使用

{-# LANGUAGE RebindableSyntax #-}

允许您重新定义用于消除(>>=)块的returndo等内容。然后你可以写下这样的东西:

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