Стандартные библиотечные функции, повторное использование кода. Кроме того, использование круглых скобок и интервалы действительно испорчены.
evaluate (V a) l =
case lookup a l
of Just x -> x
Nothing -> error $ "Unbound variable: " ++ show a
-- same as
evaluate (V a) l = maybe (error $ "Unbound variable: " ++ show a) id $ lookup a l
evaluate (Negation a) l = not $ evaluate a l
evaluate (Implication a b) l = evaluate (Negation a `Disjunction` b) l
Теперь вы хотите generateTruthTable
? Это легко, просто возьмите все возможные состояния логических переменных и прикрепите вычисленное выражение к концу каждой.
generateTruthTable :: [Variable] -> LogicExpr -> [[(Variable, Bool)]]
generateTruthTable vs e = [l ++ [('E', evaluate e l)] | l <- allPossible vs]
Если бы только у вас была функция для генерации всех этих возможных состояний.
allPossible :: [Variable] -> [[(Variable, Bool)]]
Следуя моему функциональному инстинкту, я чувствую, что это должен быть катаморфизм. В конце концов, ему нужно просмотреть все в списке, но вернуть что-то с другой структурой, и его, вероятно, можно разбить простым способом, потому что это класс CS начального уровня. (Меня не волнует номер курса, это вводный материал.)
allPossible = foldr step initial where
step v ls = ???; initial = ???
Теперь foldr :: (a -> b -> b) -> b -> [a] -> b
, поэтому первые два параметра должны быть step :: a -> b -> b
и initial :: b
. Теперь allPossible :: [Variable] -> [[(Variable, Bool)]] = foldr step initial :: [a] -> b
. Хм, это должно означать, что a = Variable
и b = [[(Variable, Bool)]]
. Что это означает для step
и initial
?
step :: Variable -> [[(Variable, Bool)]] -> [[(Variable, Bool)]]
initial :: [[(Variable, Bool)]]
Интересно. Каким-то образом должен быть способ step
из списка состояний переменных и добавить к нему одну переменную и некоторый initial
список без переменных вообще.
Если ваш разум уже сумел «щелкнуть» по парадигме функционального программирования, этого должно быть более чем достаточно. В противном случае вы в значительной степени облажались через пару часов, когда должно быть задание, независимо от того, какие инструкции вы здесь получили. Удачи, и если вы все еще застряли после срока выполнения задания, вам следует спросить своего профессора или задать несрочный вопрос здесь.
Если у вас возникли основные проблемы с удобством использования языка («каков синтаксис», «какова семантика времени выполнения», «есть ли ранее существовавшие функции для xxx» и т. Д.) :
- Язык и библиотеки Haskell 98 - это свободно доступное каноническое определение базового языка и библиотек. Дополнительные ссылки доступны в вики-странице Haskell.
- Для языковых расширений после 98 см. GHC документация.
- GHC, Hugs и другие современные реализации Haskell также предоставляют гораздо более богатую стандартную библиотеку, чем указано в Haskell 98. Полная документация для иерархические библиотеки также доступны в Интернете.
- Hooge - это специализированная поисковая машина для расширенных стандартных библиотек Haskell. Hayoo! аналогичен, но также охватывает HackageDB, коллекция библиотек Haskell, выходящая далеко за рамки стандартного распространения.
Я надеюсь, что ваш класс предоставил аналогичные ресурсы, но если нет, все вышеперечисленное легко найти с помощью поиска Google.
При наличии надлежащих ссылок любой программист, достойный его или ее соли, должен иметь возможность понять синтаксис любого нового языка в течение нескольких часов и иметь рабочее представление о среде выполнения в течение нескольких дней. Конечно, освоение новой парадигмы может занять много времени, и несколько несправедливо заставлять учеников придерживаться тех же стандартов, но для этого и предназначен класс.
Вопросы о проблемах более высокого уровня в Stack Overflow могут потребовать меньше ответов, но они также будут предоставлены с гораздо меньшей раздражительностью :) Вопросы домашнего задания относятся к категории «делай мою работу за меня!» в глазах большинства людей.
Спойлер
Пожалуйста, не обманывай. Однако просто чтобы вы почувствовали, насколько потрясающие вещи можно делать в Haskell ...
{-# LANGUAGE FlexibleInstances, UndecidableInstances #-}
{-# LANGUAGE OverlappingInstances, PatternGuards #-}
module Expr (Ring(..), (=:>), Expr(..), vars, eval, evalAll) where
import Control.Monad.Error
infixl 5 =:>, :=>
infixl 6 +:, -:, :+, :-
infixl 7 *:, :*
class (Eq a) => Ring a where
(+:) :: a -> a -> a; (-:) :: a -> a -> a; x -: y = x +: invert y
(*:) :: a -> a -> a; invert :: a -> a; invert x = zero -: x
zero :: a; one :: a
(=:>) :: (Ring a) => a -> a -> a
(=:>) = flip (-:)
instance (Num a) => Ring a where
(+:) = (+); (-:) = (-); (*:) = (*)
invert = negate; zero = 0; one = 1
instance Ring Bool where
(+:) = (||); (*:) = (&&)
invert = not; zero = False; one = True
data Expr a b
= Expr a b :+ Expr a b | Expr a b :- Expr a b
| Expr a b :* Expr a b | Expr a b :=> Expr a b
| Invert (Expr a b) | Var a | Const b
paren :: ShowS -> ShowS
paren ss s = '(' : ss (')' : s)
instance (Show a, Show b) => Show (Expr a b) where
showsPrec _ (Const c) = ('@':) . showsPrec 9 c
showsPrec _ (Var v) = ('$':) . showsPrec 9 v
showsPrec _ (Invert e) = ('!':) . showsPrec 9 e
showsPrec n e@(a:=>b)
| n > 5 = paren $ showsPrec 0 e
| otherwise = showsPrec 7 a . ('=':) . ('>':) . showsPrec 5 b
showsPrec n e@(a:*b)
| n > 7 = paren $ showsPrec 0 e
| otherwise = showsPrec 7 a . ('*':) . showsPrec 7 b
showsPrec n e | n > 6 = paren $ showsPrec 0 e
showsPrec _ (a:+b) = showsPrec 6 a . ('+':) . showsPrec 6 b
showsPrec _ (a:-b) = showsPrec 6 a . ('-':) . showsPrec 6 b
vars :: (Eq a) => Expr a b -> [a]
vars (a:+b) = vars a ++ vars b
vars (a:-b) = vars a ++ vars b
vars (a:*b) = vars a ++ vars b
vars (a:=>b) = vars a ++ vars b
vars (Invert e) = vars e; vars (Var v) = [v]; vars _ = []
eval :: (Eq a, Show a, Ring b, Monad m) => [(a, b)] -> Expr a b -> m b
eval m (a:+b) = return (+:) `ap` eval m a `ap` eval m b
eval m (a:-b) = return (-:) `ap` eval m a `ap` eval m b
eval m (a:*b) = return (*:) `ap` eval m a `ap` eval m b
eval m (a:=>b) = return (=:>) `ap` eval m a `ap` eval m b
eval m (Invert e) = return invert `ap` eval m e
eval m (Var v)
| Just c <- lookup v m = return c
| otherwise = fail $ "Unbound variable: " ++ show v
eval _ (Const c) = return c
namedProduct :: [(a, [b])] -> [[(a, b)]]
namedProduct = foldr (\(v, cs) l -> concatMap (\c -> map ((v, c):) l) cs) [[]]
evalAll :: (Eq a, Show a, Ring b) => [b] -> a -> Expr a b -> [[(a, b)]]
evalAll range name e =
[ vs ++ [(name, either error id $ eval vs e)]
| vs <- namedProduct $ zip (vars e) (repeat range)
]
$ ghci
GHCi, version 6.10.2: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer ... linking ... done.
Loading package base ... linking ... done.
Prelude> :l Expr.hs
[1 of 1] Compiling Expr ( Expr.hs, interpreted )
Ok, modules loaded: Expr.
*Expr> mapM_ print . evalAll [1..3] 'C' $ Var 'A' :* Var 'B'
Loading package mtl-1.1.0.2 ... linking ... done.
[('A',1),('B',1),('C',1)]
[('A',1),('B',2),('C',2)]
[('A',1),('B',3),('C',3)]
[('A',2),('B',1),('C',2)]
[('A',2),('B',2),('C',4)]
[('A',2),('B',3),('C',6)]
[('A',3),('B',1),('C',3)]
[('A',3),('B',2),('C',6)]
[('A',3),('B',3),('C',9)]
*Expr> let expr = Var 'A' :=> (Var 'B' :+ Var 'C') :* Var 'D'
*Expr> expr
$'A'=>($'B'+$'C')*$'D'
*Expr> mapM_ print $ evalAll [True, False] 'E' expr
[('A',True),('B',True),('C',True),('D',True),('E',True)]
[('A',True),('B',True),('C',True),('D',False),('E',False)]
[('A',True),('B',True),('C',False),('D',True),('E',True)]
[('A',True),('B',True),('C',False),('D',False),('E',False)]
[('A',True),('B',False),('C',True),('D',True),('E',True)]
[('A',True),('B',False),('C',True),('D',False),('E',False)]
[('A',True),('B',False),('C',False),('D',True),('E',False)]
[('A',True),('B',False),('C',False),('D',False),('E',False)]
[('A',False),('B',True),('C',True),('D',True),('E',True)]
[('A',False),('B',True),('C',True),('D',False),('E',True)]
[('A',False),('B',True),('C',False),('D',True),('E',True)]
[('A',False),('B',True),('C',False),('D',False),('E',True)]
[('A',False),('B',False),('C',True),('D',True),('E',True)]
[('A',False),('B',False),('C',True),('D',False),('E',True)]
[('A',False),('B',False),('C',False),('D',True),('E',True)]
[('A',False),('B',False),('C',False),('D',False),('E',True)]
person
ephemient
schedule
05.06.2009