Функция Haskell, которая принимает в качестве аргумента функцию с переменным числом аргументов (и возвращает что-то еще, кроме этой функции) без FlexibleInstances, чистый Haskell2010

возможно ли выразить следующую программу Haskell без 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)]

Это вдохновлено ответом на Как написать функцию Haskell, которая принимает вариативная функция в качестве аргумента .

Я подозреваю, что проблема в том, что истина возвращает что-то еще, кроме функции, которая принимает в качестве аргумента (которая возвращает 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

11
задан Community 23 May 2017 в 12:20
поделиться