Currently I'm trying to learn Haskell by following a FP in Haskell course from University of Pennsylvania.
In one of the assignments, I had to define the following type classes to implement expression evaluating calculator :
class Expr a where
mul :: a -> a -> a
add :: a -> a -> a
lit :: Integer -> a
class HasVars a where
var :: String -> a
And a data type which mimics a math expression which can contain, addition, multiplication of integers and also can hold a variable in the expression.
data VarExprT = VarLit Integer
| VarAdd VarExprT VarExprT
| VarMul VarExprT VarExprT
| Var String
deriving (Show, Eq)
instance HasVars VarExprT where
var = Var
instance Expr VarExprT where
lit = VarLit
add = VarAdd
mul = VarMul
Now to simulate the operations of adding, multiplying in an expression with variables, I had to create instances of above typeclasses as below :
instance HasVars (M.Map String Integer -> Maybe Integer) where
var str = \mMap -> M.lookup str mMap
instance Expr (M.Map String Integer -> Maybe Integer) where
lit x = \mMap -> Just x
add f1 f2 = \mMap -> if isNothing (f1 mMap) || isNothing (f2 mMap)
then
Nothing
else
Just (fromJust (f1 mMap) + fromJust (f2 mMap))
mul f1 f2 = \mMap -> if isNothing (f1 mMap) || isNothing (f2 mMap)
then
Nothing
else
Just (fromJust (f1 mMap) * fromJust (f2 mMap))
And to actually evaluate expressions the below function was provided :
withVars :: [(String, Integer)] -> (M.Map String Integer -> Maybe Integer)-> Maybe Integer
withVars vs exp = exp $ M.fromList vs
So using above function in ghci looks like below :
*Calc> withVars [("x", 6)] $ add (lit 3) (mul (lit 6) (var "x"))
Just 39
*Calc> withVars [("x", 6)] $ add (lit 3) (var "y")
Nothing
So my query is the following :
In a normal expression in Haskell, expressions are evaluated only when they are needed which is still not very intuitive to me, but I sort of get it.
But in first expression above, how will it the internal evaluation work for the expression in the condition ?
Because as I understand, first add is taking place so the if condition will be checked.
And the condition will have to get evaluated to a point where it comes to True or evaluate fully to False. But in the second expression of the || it is going to try to evaluate the mul expression (mul (lit 6) (var "x")) mMap corresponding to f2 mMap.
And now again there is an if condition in mul. So I'm confused as to how exactly will the evaluations play out because of the recurring if conditions coming in the middle of expression evaluations.
PS : The M.Map and so on is because of import qualified Data.Map as M
The definition of || is lazy, and will evaluate the second argument only when needed, i.e. when the first argument is false.
You can test it in GHCi, observing that the following does not trigger the error.
> True || error "ouch!"
True
In your case, isNothing (f1 mMap) || isNothing (f2 mMap) will first evaluate isNothing (f1 mMap) and if that is true it will skip the evaluation of isNothing (f2 mMap).
Note that this is essentially the same "short-circuiting" semantics of the boolean operator || which is commonly found in C, C++, Java, and many other languages. There, evaluating f() || g() won't call g unless f() evaluates to false.
Minor digression on the style
You shouldn't use fromJust -- that's a partial function that can crash the program if you forget to check for Nothing. In your code you do check against that, but that's not the recommended style.
You code suffers from "boolean blindness": you have two Maybe Integer values, and instead of testing them directly, you first transform them into boolean, losing precious information (the integer inside). Since you lost that information in the test, you then need to resort to dangerous tools like fromJust to recover the information you lost in the test.
The common practice here is to avoid booleans, avoid if, and use pattern matching to test the Maybe Integer values directly.
add f1 f2 = \mMap -> case (f1 mMap, f2 mMap) of
(Nothing, _ ) -> Nothing
(_ , Nothing) -> Nothing
(Just i1, Just i2) -> Just (i1 + i2)
(There are library functions to shorten that, but it's irrelevant).
The code above uses no booleans at all. It also will evaluate f2 mMap only when needed, i.e. only if the (_ , Nothing) -> Nothing line is reached, i.e. only when f1 mMap was not a Nothing. This provides the same lazy semantics as the previous code using booleans and ||.
Related
I said in this question that I didn't understand the source code of findIndices.
In fact I didn't pay enough attention and I didn't see that there are two definitions of this function:
findIndices :: (a -> Bool) -> [a] -> [Int]
#if defined(USE_REPORT_PRELUDE)
findIndices p xs = [ i | (x,i) <- zip xs [0..], p x]
#else
-- Efficient definition, adapted from Data.Sequence
{-# INLINE findIndices #-}
findIndices p ls = build $ \c n ->
let go x r k | p x = I# k `c` r (k +# 1#)
| otherwise = r (k +# 1#)
in foldr go (\_ -> n) ls 0#
#endif /* USE_REPORT_PRELUDE */
I understand the first definition, the one I didn't see. I don't understand the second one. I have a couple of questions:
what is if defined(USE_REPORT_PRELUDE) ?
can one explain the second definition ? What are build, I#, +#, 1# ?
why the second definition is inlined, not the first one ?
The CPP extensions enables the C preprocessor, as for the C programming language. Here, it is used to test if the flag USE_REPORT_PRELUDE was set during compilation. According to that flag, the compiler uses the #if or the #else variant of code.
build is a function which could be defined as
build f = f (:) []
So, using build (\c n -> ... essentially lets c to the "cons" (:), and n to the "nil" [].
This is not used for convenience: it is not convenient at all! However, the compiler optimizer works great with build and foldr combined, so the code is written here in a weird way to take advantage of that.
Further, I# ... is the low-level constructor for integers. When we normally write
x :: Int
x = 4+2
GHC implements x (very roughly) with a pointer to some memory that reads as unevaluated: 4+2. After x is forced the first time, this memory gets overwritten with evaluated: I# 6#. This is needed to implement laziness.
The "boxing" here refers to the indirection through a pointer.
Instead, the type Int# is a plain machine integer, with no pointers, no indirection, no unevaluated expressions. It is strict (instead of lazy), but being more low-level it is more efficient. One creates a value as in
x' :: Int#
x' = 6#
x :: Int
x = I# x'
Indeed, Int is defined as newtype Int = I# Int#.
Keep in mind that this is not standard Haskell, but GHC-specific low-level details. In normal code, you should not need to use such unboxed types. In libraries, the authors do that to achieve a little more performance, but that's it.
Sometimes, even if in our code we only use Ints, GHC is smart enough to automatically convert our code to using Int# and achieve more efficiency, avoiding the boxing. This can be observed if we ask GHC to "dump Core" so that we can see the result of the optimization.
For instance, compiling
f :: Int -> Int
f 0 = 0
f n = n + f (n-1)
GHC produces a lower level version (this is GHC Core, not Haskell, but it is similar enough to be understood):
Main.$wf :: GHC.Prim.Int# -> GHC.Prim.Int#
Main.$wf = \ (ww_s4un :: GHC.Prim.Int#) ->
case ww_s4un of ds_X210 {
__DEFAULT ->
case Main.$wf (GHC.Prim.-# ds_X210 1#) of ww1_s4ur { __DEFAULT ->
GHC.Prim.+# ds_X210 ww1_s4ur
};
0# -> 0#
}
Notice the number of arguments to go. go x r k = ... === go x r = \k -> .... This is the standard trick to arrange for left-to-right information flow while folding the list (go is used as the reducer function, in foldr go (\_ -> n) ls 0#). Here, it's the counting of [0..], explicated as the initial k=0 and the (k + 1) on each step (k is an unfortunate naming choice, i seems better; k is overloaded with the irrelevant "constant" and "continuation", not just "counter" which was probably the intended meaning here).
The foldr/build (sic) fusion (linked to by luqui in the comments) turns foldr c n $ findIndices p [a1,a2,...,an] into a loop, exposing the inner foldr of the findIndices definition, avoiding building the actual list structure of the result of the findIndices call:
build g = g (:) []
foldr c n $ build g = g c n
foldr c n $ findIndices p [a1,a2,...,an]
==
foldr c n $ build g where {g c n = ...}
=
g c n where {g c n = ...}
=
foldr go (const n) [a1,a2,...,an] 0 where {go x r k = ...}
=
go a1 (foldr go (const n) [a2,...,an]) 0
=
let { x=a1, r=foldr go (const n) [a2,...,an], k=0 }
in
if | p x -> c (I# k) (r (k +# 1#)) -- no 'cons' (`:`), only 'c'
| otherwise -> r (k +# 1#)
=
....
So you see, it's a standard trick to have foldr define a function which expects one more input argument, to arrange the left-to-right information flow while processing the input list.
All the stuff with the hash sign are "primitive" or "closer-to-machine-level" entities. I# is a primitive Int constructor; 0# is a machine-level 0; etc.. This may or may not be exactly correct, but it should be close enough.
foldr/build fusion seems a particular case of transducers-based code transformation, which is based on the fact that nested folds are fused by composing their reducers' transformers (aka transducers), as in
foldr c n $
foldr (tr2 c2) n2 $
foldr (tr3 c3) n3 xs
=
foldr (tr2 c) n $ -- fold "replaces" the constructor nodes with its reducer
foldr (tr3 c3) n3 xs -- so just use the outer reducer in the first place!
=
foldr (tr3 (tr2 c)) n xs
=
foldr ((tr3 . tr2) c) n xs
and build g === foldr . tr for some appropriate choice of tr for a given g, so that
build g = g c n = (foldr . tr) c n = foldr (tr c) n
As for USE_REPORT_PRELUDE, again, I can't say this with any authority, but I always assumed that it is the compilation flag which is enabled when the mock definitions from the Haskell Report are used as actual code, even though they were intended as an executable specification.
i have this problem:
i want to have a list of strings representing math expression, and a map of arguments to replace the variables.
so if my list is like ["x","+","y","-","5"] and arguments are [("x","5"),("y","4")]
the function should return ["5","+","4","-","5"]
i have this function to find key from map (from the Learn you a haskell book)
findKey :: (Eq k) => k -> [(k,v)] -> Maybe v
findKey key [] = Nothing
findKey key ((k,v): xs) =
if key == k
then Just v
else findKey key xs
and then my function to replace the variables with values
takeValuesFromMap (x:str) m result
|x == [] = result
|findKey x m == Nothing = takeValuesFromMap str m (result++[x])
|otherwise = takeValuesFromMap str m result++[fromJust (findKey x m)]
if no match in the map, we pass the regular string. Otherwise we pass to the result the value staying next to the key that matches.
but in the end when i call
takeValuesFromMap ["x","+","y","-","5"] (Map.fromList [("x","5"),("y","4")]) []
it says
Solver.hs:63:48:
Couldn't match expected type `[([Char], [Char])]'
with actual type `Map.Map [Char] [Char]'
In the return type of a call of `Map.fromList'
In the second argument of `takeValuesFromMap', namely
`(Map.fromList [("x", "5"), ("y", "4")])'
In the expression:
takeValuesFromMap
["x", "+", "y", "-", ....]
(Map.fromList [("x", "5"), ("y", "4")])
[]
any idea how to fix this?
I'm going to take a different track here, and suggest that you don't solve this problem. The reason is that the list ["x","+","y","-","5"] is a very poor representation of the algebraic expression x + y - 5. I don't know exactly what you're trying to do, but a better approach would represent the expression as an abstract syntax tree, using an algebraic datatype.
So for example, we could use the following type to represent the expressions:
data Expr a = Variable String
| Literal a
| Plus Expr Expr
| Minus Expr Expr
Given this type, your example goes like this:
example :: Expr Integer
example = Minus (Plus (Var "x") (Var "y")) (Literal 5)
It's easy to write a function that evaluates expressions of this type, given a Map from variable names to values:
-- | Evaluate an expression, reading variable's values from the given environment
-- (the Map argument). Returns Nothing if any of the variables is undefined.
eval :: Num a => Expr a -> Map String a -> Maybe a
eval (Variable v) env = Map.lookup v env
eval (Literal x) _ = Just x
eval (Plus x y) env =
-- If this is confusing, read up on the Maybe monad in Learn You a Haskell
do x' <- eval x env
y' <- eval y env
return (x + y)
eval (Minus x y) env =
do x' <- eval x env
y' <- eval y env
return (x - y)
More complex, but well worth learning, is then to write a parser that takes a string and turns it into an Expr. If you're reading Learn You A Haskell, you may want to first get more comfortable with monads and applicatives. But when you're ready to take that step, there's a number of pages on the web with calculator parser examples:
http://meta-meta.blogspot.com/2007/10/simple-infix-calculator-in-haskell.html
http://www.youtube.com/playlist?list=PL_xuff3BkASMOzBr0hKVKLuSnU4UIinKx
http://haskelladdict.wordpress.com/2009/02/01/a-nice-little-calculator-implemented-in-haskell-and-parsec/
Though you may want to read this part of Real World Haskell first:
http://book.realworldhaskell.org/read/using-parsec.html
In findKey you require an association list, but you are actually using a Map. So, one way to fix it woulde be to remove Map.fromList.
Another point: Never replace pattern matching with equality checks! So please write:
| [] <- x = ...
| Nothing <- findKey x m = ...
Inspect the type of Map.fromList. Am I right in assuming that you take Map from Data.Map? If so:
:t Data.Map.fromList
Data.Map.fromList :: Ord k => [(k, a)] -> Map k a
So, this function returns Map, but your findKey actuall wants a list of tuples [([Char],[Char])]. You have got two choices now:
Use a function from Data.Map instead of your findKey to lookup a key.
Use another function to build your list.
I'm going to override the equal class for Dynamic data type in this way:
instance Eq Dynamic where
x==y = dynamicEq x y
dynamicEq :: Dynamic -> Dynamic -> Bool
dynamicEq x y = ConstrName x == ConstrName y && sameSlots(slots x)(slots y)
where
sameSlots [] [] = True
sameSlots ((x::Eq a => a):xs)(y:ys) = x == fromDynamic y && sameSlots xs ys
can you name or declare any function that can return the values of ConstrName and slots for me? Maybe using Tycon or something similar?
Never fiddled with this stuff, but here may be two partial answers which could be enough for you. I'm afraid it's not a general solution nor a way to make Dynamic and instance of Eq (it would probably be one already if it was easy).
But in your last comment you stated that you only wanted to compare your own types. So, partial answer 1:
You can of course compare two Dynamics if you guess their type. For example:
eqInt :: Int -> Int -> Bool
eqInt = (==)
x = toDyn (3::Int)
y = toDyn (3::Int)
z = toDyn (4::Int)
compareDynamic :: (Typeable a, Eq a) =>
(a -> a -> Bool) ->
Dynamic -> Dynamic -> Maybe Bool
compareDynamic eq x y = do
let dEq = toDyn eq
fn1 <- dynApply dEq x
res <- dynApply fn1 y
fromDynamic res
And now:
...> compareDynamic eqInt x y
Just True
...> compareDynamic eqInt x z
Just False
However, despite the misleading polymorphic type of compareDynamic, you can only pass in a monomorphic comparison function. See:
...> compareDynamic (==) x z
Nothing
I suppose that is because the type system has no way of knowing which instance of (==) it should actually use here. I kept compareDynamic polymorphic though so you don't have to create separate functions for each type.
Now, since you only want to compare your own types, you could just have a list of comparison functions which you try in order:
eqs = [eqMyTypeA, eqMyTypeB, eqMyTypeC]
comp dynA dynB = catMaybes $ map (\eq -> eq dynA dynB) eqs
And [] would denote two different types, [Just False] the same type with different values and [Just True] the same type and value.
In case you have a large number of types, you can also determine the constructor before doing any comparison, (this is partial answer 2) and select the right function depending on it. It the constructors are different, you wouldn't have to try compare at all:
constructor :: Dynamic -> TyCon
constructor = typeRepTyCon . dynTypeRep
And have a lookup table matching constructors to equality functions.
One closing remark: Think twice if you need this. Think thrice if you need Dynamic at all, most Haskell programs don't. Isn't it just Java thinking sneaking in?
I'm trying to write a program in Haskell
that gets a list (of integer) and prints out the number of elements that are bigger than the list's average
So far I tried
getAVG::[Integer]->Double
getAVG x = (fromIntegral (sum x)) / (fromIntegral (length x))
smallerThanAVG:: [Integer]->Integer
smallerThanAVG x = (map (\y -> (if (getAVG x > y) then 1 else 0)) x)
For some reason I'm getting this error
Couldn't match expected type `Double'
against inferred type `Integer'
Expected type: [Double]
Inferred type: [Integer]
In the second argument of `map', namely `x'
It could be that I haven't written the logic correctly, although I think I did..
Ideas?
These errors are the best kind, because they pinpoint where you have made a type error.
So let's do some manual type inference. Let's consider the expression:
map (\y -> (if (getAvg x > y) then 1 else 0)) x
There are a few constraints we know off the bat:
map :: (a -> b) -> [a] -> [b] -- from definition
(>) :: Num a => a -> a -> Bool -- from definition
getAvg :: [Integer] -> Double -- from type declaration
1, 0 :: Num a => a -- that's how Haskell works
x :: [Integer] -- from type declaration of smallerThanAVG
Now let's look at the larger expressions.
expr1 = getAvg x
expr2 = (expr1 > y)
expr3 = (if expr2 then 1 else 0)
expr4 = (\y -> expr3)
expr5 = map expr4 x
Now let's work backwards. expr5 is the same as the RHS of smallerThanAVG, so that means it has the same result type as what you've declared.
expr5 :: Integer -- wrong
However, this doesn't match our other constraint: the result of map must be [b] for some b. Integer is definitely not a list (although if you get facetious, it could be coerced into a list of bits). You probably meant to sum that list up.
expr6 = sum expr5
sum :: Num a => [a] -> a
Now let's work forwards.
expr1 :: Double -- result type of getAvg
y :: Double -- (>) in expr2 requires both inputs to have the same type
expr4 :: (Integer -> [a]) -- because for `map foo xs` (expr5)
-- where xs :: [a], foo must accept input a
y :: Integer -- y must have the input type of expr4
Herein lies the conflict: y cannot be both a Double and an Integer. I could equivalently restate this as: x cannot be both a [Double] and [Integer], which is what the compiler is saying. So tl;dr, the kicker is that (>) doesn't compare different types of Nums. The meme for this sort of problem is: "needs more fromIntegral".
(getAvg x > fromIntegral y)
Your code has two errors.
Although the type signature in the code declares that smallerThanAVG x evaluates to an Integer, its code is map ... x, which clearly evaluates to a list instead of a single Integer.
In the code getAVG x > y, you are comparing a Double to an Integer. In Haskell, you can only compare two values of the same type. Therefore, you have to use fromIntegral (or fromInteger) to convert an Integer to a Double. (This is essentially what caused the error message in the question, but you have to get used to it to figure it out.)
There are several ways to fix item 1 above, and I will not write them (because doing so would take away all the fun). However, if I am not mistaken, the code you are aiming at seems like counting the number of elements that are smaller than the average, in spite of what you write before the code.
Styling tips:
You have many superfluous parentheses in your code. For example, you do not have to parenthesize the condition in an if expression in Haskell (unlike if statement in C or Java). If you want to enjoy Haskell, you should learn Haskell in a good style instead of the Haskell which just works.
You call the variable which represents a list “x” in your code. It is conventional to use a variable name such as xs to represent a list.
Others have explained the errors beautifully.
I'm still learning Haskell but I'd like to provide an alternative version of this function:
greaterThanAvg :: [Int] -> [Int]
greaterThanAvg xs = filter (>avg) xs
where avg = sum xs `div` length xs
cnt = length $ greaterThanAvg [1,2,3,4,5]
I have 2 Question about 2 haskell functions
flipSymbol :: Model -> Atom -> Model This function must take a Model and an Atom and flip the truth value of the atom in the model. Now I was thinking of writing this function like this:...
flipSymbol m a = map f m
where
f (atom, value) = if a == atom then (atom, not value) else (atom, value)
Is there a better way?
The second one is a something more complicated and I need some help with it if possible..
In order to check the satisfiability of a formula in a given model we propagate the effects of assigning a truth value to an atom in a formula. Assume an atom to which we assign the value True. The following effects
can be applied to the formula:
The positive literals have the same True value and, therefore, any clauses that contain them are removed from the formula. This is to indicate that these clauses could be satisfied and hence no longer affect the satisfiability of the formula.
The negated literals have a value of False and are, therefore, removed from any clause they are in. This is to indicate that these clauses are still not satisfied and can only be made true by one of the other literals obtaining a value of True. In the case where False is assigned to the atom, the positive literals will now be false and should be removed
from their clauses while the negative literals will become true and have their clauses removed from the formula.
For example, in the formula (P _ Q _ R) ^ (:P _ Q _ :R) ^ (P _ :Q), assume we assign True to P. Then the clauses containing P, ie. (P _ Q _ R) and (P _ :Q) are removed from the formula, whereas :P is removed from any clause it is in, ie. (:P _ Q _ :R). This results in the formula (Q _ :R). On the other hand, if we assign False to P, we then remove (:P _ Q _ :R) from the formula and P from its clauses, thus obtaining (Q _ R) ^ (:Q).
The overall formula is satisfiable if it can be reduced to the empty list since in this case all the clauses were satisfied. If there is an empty list within the overall formula then that means that a clause was not satisfied and hence the formula can not be satisfied with the assignment that led to this state.
assign :: (Atom,Bool) -> Formula -> Formula The assign function should take an (Atom,Bool) pair and a formula and propagate the effects of assigning the given truth value to the atom in the formula as described above.
The code(on which I received help from here also):
module Algorithm where
import System.Random
import Data.Maybe
import Data.List
type Atom = String
type Literal = (Bool,Atom)
type Clause = [Literal]
type Formula = [Clause]
type Model = [(Atom, Bool)]
type Node = (Formula, ([Atom], Model))
-- This function takess a Clause and return the set of Atoms of that Clause.
atomsClause :: Clause -> [Atom]
atomsClause = undefined
-- This function takes a Formula returns the set of Atoms of a Formula
atoms :: Formula -> [Atom]
atoms = nub . map snd
-- This function returns True if the given Literal can be found within
-- the Clause.
isLiteral :: Literal -> Clause -> Bool
isLiteral = isLiteral = any . (==)
-- this function takes a Model and an Atom and flip the truthvalue of
-- the atom in the model
flipSymbol :: Model -> Atom -> Model -- is this ok?
flipSymbol m a = map f m where
f (atom, value) = if a == atom
then (atom, not value)
else (atom, value)
assign :: (Atom,Bool) -> Formula -> Formula
assign = undefined --any advice here?
At a glance, I can't see any way to improve your first formula, maybe you may use logical functions instead of a if-then-else, it's faster:
flipSymbol m a = map f m where
f (atom, value) = (atom, value /= (a == atom))
Notice: /= for Bool is basically xor.
To your last question:
The basic idea is to compare the Atoms, incorporate the Bool-values and fiddeling around with logical ops to get your result. Basically, it looks like this:
assign :: (Atom,Bool) -> Formula -> Formula
assign (a,b) = map . (map f) where
f (x,b) = (x,(x==a)&&b)