John C.
John C.

Reputation: 445

How to take an output list of a function as input to another function in Haskell?

Let's say that we have a function truthtable ::BoolExpr -> [([Variable], Bool)] that returns the value in List of ordered pairs of the variable and it's Bool evaluation.

functions are defined as following

module BoolExpr (Variable, BoolExpr(..), evaluate) where
import Data.List
import System.IO

type Variable = Char
data BoolExpr = T
 |F
 |Var Variable
 |Not BoolExpr
 |And BoolExpr BoolExpr
 |Or BoolExpr BoolExpr
 deriving(Show)


-- evaluates an expression
evaluate :: BoolExpr -> [Variable] -> Bool
evaluate T _            = True
evaluate F _            = False
evaluate (Var v) vs     = v `elem` vs
evaluate (Not e) vs     = not (evaluate e vs)
evaluate (And e1 e2) vs = evaluate e1 vs && evaluate e2 vs
evaluate (Or  e1 e2) vs = evaluate e1 vs || evaluate e2 vs

--remove duplicates
rmdups :: (Ord a) => [a] -> [a]
rmdups = map head . group . sort


variables :: BoolExpr -> [Variable]
variables T = []
variables F = []
variables (Var e1) = [e1]
variables (And e1 e2) =rmdups$ sort $ variables e1 ++ variables e2
variables (Or e1 e2) =rmdups$ sort $ variables e1 ++ variables e2
variables (Not e) = variables e



 --function to get the subsets of a list
subsets :: [Variable] -> [[Variable]]
subsets [] = [[]]
subsets (x:xs) = [zs | ys <- subsets xs, zs <- [ys, (x:ys)]]


Now the function subsets return all possible subsets in a string eg.

> subsets "abc"
["","c","b","bc","a","ac","ab","abc"]

Now how to take each element in this list and put it here

evaluate (And (Var 'a') (Or (Var 'c') (Var 'b'))) "HERE"

I know how to do something like this in C using iteration over the list and doing the calculation.

My approach : number of subsets of string= 2^n, where n is the number of elements

now I would use a scenario like this:

let x=0
iterate form x to (n-1) (subsets $ variables (And e1 e2)) !! x

i know that !! operator allow to pick element from the list according to the index written. Finally the result of the chunk above is applied to the evaluate function at the end part HERE. that what the function truthtable evaluate as a whole

> truthtable (And (Var 'a') (Or (Var 'c') (Var 'b')))

[("",False),("c",False),("b",False),("bc",False),("a",False),("ac",True),("ab",True),("abc",True)]

any ideas how to apply this in Haskell

Upvotes: 1

Views: 710

Answers (2)

Will Ness
Will Ness

Reputation: 71065

> truthtable (And (Var 'a') (Or (Var 'c') (Var 'b')))

[("",False),("c",False),("b",False), ...

You mean,

truthtable expr =
            [ evaluate expr s | s <- subsets (variables expr) ]
{-
 expr ::               BoolExpr
 variables ::          BoolExpr -> [Variable]
 variables expr ::                 [Variable]
 subsets ::                        [Variable] -> [[Variable]]
 subsets (variables expr) ::                     [[Variable]]
 s ::                                             [Variable]
 evaluate ::           BoolExpr                -> [Variable]  ->  Bool
 evaluate              expr                       s           ::  Bool
[evaluate              expr                       s         ] :: [Bool]
-----------------------------------------------------------------------
truthtable ::          BoolExpr                               -> [Bool]
-}

The [ foo | x <- xs ] syntax is known as "list comprehension".

It is analogous to a loop in imperative paradigm, and can be read as "the list of foos, for x in xs". It is also equivalent to map (\ x -> foo ) xs; also

  [ foo | x <- [a, b, c] ]
=
  [ foo | x <- [a]   ++              [b]   ++              [c] ]
=
  [ foo | x <- [a] ] ++ [ foo | x <- [b] ] ++ [ foo | x <- [c] ]
=
  [ foo | let x=a  ] ++ [ foo | let x=b  ] ++ [ foo | let x=c  ]

:: means "has type".

Upvotes: 1

Daniel Wagner
Daniel Wagner

Reputation: 152707

Now how to take each element in this list and put it here

evaluate (And (Var 'a') (Or (Var 'c') (Var 'b'))) "HERE"

Like this:

map (evaluate (And ...)) (subsets "abc")

Upvotes: 4

Related Questions