2014-02-08 14 views
2

(我意识到SO上有一个similar question,但我不认为这是一个骗局,因为我试图实现的函数是递归的,不使用列表或lambda表达式我想知道如何以这种方式实现它,即使它们在功能上是等价的,主要是为了更好地理解Haskell。)Haskell中的递归重言式检查器

我在学习如何使函数检查给定的布尔函数是重言式。下面是从书中我读,与1个变量检查​​布尔函数的样本函数:

valid1 :: (Bool -> Bool) -> Bool 
valid1 bf = (bf True) && (bf False) 

和2和3个变量:

valid2 :: (Bool -> Bool -> Bool) -> Bool 
valid2 bf = (bf True True) 
      && (bf True False) 
      && (bf False True) 
      && (bf False False) 

valid3 :: (Bool -> Bool -> Bool -> Bool) -> Bool 
valid3 bf = and [ bf p q r | p <- [True,False], 
          q <- [True,False], 
          r <- [True,False]] 

但在我看来,应该有对于每个具有不同数量变量的布尔函数使用单独的检查器函数是一种更好的方法。例如,我们可以做出这样的:

validR n bf :: Int -> (Bool -> a) -> Bool 
validR n bf | n == 1 = valid1 bf 
      | otherwise = (validR (n-1) (bf True)) && (validR (n-1) (bf False)) 

其中n是变量bf的数量,这是正在检查的布尔函数。当给定一个具有n> 1个变量的布尔函数bf时,该函数将转入检查bf Truebf False,最终检查所有可能的真值组合。但是当我尝试加载这个函数时,Haskell给出了错误消息“在应用程序中键入错误”。有什么办法来调整这个函数的类型声明来使它工作吗?

我是新来的Haskell所以简单的解释将非常感激。提前致谢。

回答

2

其实,这可以很容易地完成。

{-# LANGUAGE FlexibleInstances #-} 

class BooleanFunc f where 
    isTautology :: f -> Bool 

instance BooleanFunc Bool where 
    isTautology = id 
instance (BooleanFunc b) => BooleanFunc (Bool -> b) where 
    isTautology f = isTautology (f True) && isTautology (f False) 

main = do 
    print . isTautology $ \a b c d -> True || a || b || c || d 
    print . isTautology $ \a b c d ->   a || b || c || d 
+0

尝试用'-98'选项运行拥抱。一般来说,使用'ghci'可能会更好。 – ErikR