というハスケル関数は、FlexableInstancesのないHaskellプログラム、すなわち純粋なHaskell2010を表現できますか?FlexibleInstancesを持たない可変引数関数を引数としてとり、Haskell2010
{-# LANGUAGE FlexibleInstances #-}
class Funk a where truth :: a -> [Bool]
instance Funk [Bool] where truth = \x -> x
instance Funk Bool where truth = \x -> [x]
instance Funk b => Funk (Bool -> b) where
truth f = concat [truth (f True), truth (f False)]
これは、How to write a Haskell function that takes a variadic function as an argumentの答えに触発されています。
truth
は、引数として受け取る関数(Bool
ではなく、[Bool]
を返します)以外の何かを返すという問題が疑われます。
このスニペットの目的はすなわち
Main> truth (\x y -> x && y)
[True,False,False,False]
Main> truth (\x y -> x || y)
[True,True,True,False]
終わりには、真理値表は次のように、印刷する、ブール関数のためのすべての可能な構成のすべての評価のリストを与えることであり、試験および視覚化するためのいくつかのボイラープレートコードがこの機能の目的が何であるか、ここ
Main> main
T T T | T
T T F | T
T F T | T
T F F | F
F T T | T
F T F | F
F F T | T
F F F | T
:(これを生成するコードを参照するために、この記事の最後にボイラープレートを参照)
class TruthTable a where
truthTable :: Funk f => f -> a
instance TruthTable [String] where
truthTable f = zipWith (++) (hCells (div (length t) 2)) (map showBool $ truth f)
where
showBool True = "| T"
showBool False = "| F"
hCells 1 = ["T ", "F "]
hCells n = ["T " ++ x | x <- hCells (div n 2)] ++ ["F " ++ x | x <- hCells (div n 2)]
instance TruthTable [Char] where
truthTable f = foldl1 join (truthTable f)
where join a b = a ++ "\n" ++ b
instance TruthTable (IO a) where
truthTable f = putStrLn (truthTable f) >> return undefined
main :: IO()
main = truthTable (\x y z -> x `xor` y ==> z)
xor :: Bool -> Bool -> Bool
xor a b = not $ a == b
(==>) :: Bool -> Bool -> Bool
a ==> b = not $ a && not b
ああ、ありがとう。私はText.PrintfのIsCharと同様の "トリック"を見たことがあります。 – scravy