Lazy evaluations of data structures - haskell

I'm reading about lazy evaluations in haskell and have a question. For example we have following computations:
Prelude> let x = 1 + 1 :: Int
Prelude> let y = (x,x)
And after getting value of x:
Prelude> :sprint x
x = _
It's unevaluated. Ok, now let's get value of y:
Prelude> :sprint y
y = (_,_)
It is unevaluated too, because y depends on x and it's unevaluated. Now let's try the same example but without ::Int:
Prelude> let x = 1 + 1
Prelude> let y = (x, x)
Prelude> :sprint y
y = _
Why y value is _ instead (_, _) when we're trying without ::Int?
I see that they have different types:
Prelude> let x = 1 + 1
Prelude> :t x
x :: Num a => a
Prelude> let x = 1 + 1 :: Int
Prelude> :t x
x :: Int
But why values of y depends on it?
Thank you.

What is happening is that when you've specified x to have the type Num a => a, the compiler can't possibly know which instance of Num to use when performing 1 + 1. What it does instead is use defaulting. GHC defines default types for certain typeclasses so that when there's no possible way to determine what concrete type to use it can still give meaningful results without raising errors. So when you see
> let x :: Num a => a
| x = 1 + 1
> x
2
> :sprint x
x = _
This is because GHCi chooses Integer as its default type for Num, but when it performs this operation it doesn't store the result in x's memory location, since there isn't a way to know if that is even the correct answer. This is why you see x = _ from :sprint, it hasn't actually evaluated x :: Num a => a, it's evaluated x :: Integer. You can even mess with this default yourself:
> newtype MyInt = MyInt Int deriving (Eq)
>
> instance Show MyInt where
| show (MyInt i) = show i
> instance Num MyInt where
| (MyInt x) + (MyInt y) = MyInt (x - y)
| fromInteger = MyInt . fromInteger
>
> default (MyInt)
> x
0
So now we've said that 1 + 1 = 0! Keep in mind that you will probably never have a use for this functionality of GHC, but it's good to know about.

Related

Define algebra over GF4

How to define the algebraic operations over finite field power 4 (GF4) in Haskell?
I have numbers: 0, 1, 2, 3
And the operators could look like this:
(+) x y = (x + y) `mod` 4
(*) 0 y = 0
(*) 1 y = y
(*) x 0 = 0
(*) x 1 = x
(*) 2 2 = 3
(*) 3 3 = 2
(*) 2 3 = 1
(*) 3 2 = 1
Note: (*) is not multiple mod 4!
I want to get something like this:
3 * 2 :: GF4 == 1 :: GF4
I write:
class GF4 x where
(+), (*) :: x -> x -> x
instance GF4 where
0 + 0 = 0
...
2 * 3 = 1
...
But unsuccessfully! How to write an implement of this operators by type class or type?
Like this:
data GF4 = GF4_0 | GF4_1 | GF4_2 | GF4_3
deriving (Bounded, Enum, Eq, {- Ord, maybe? -} Read, Show)
instance Num GF4 where
-- A small trick to avoid having to write all the cases by hand:
-- reuse the `Num Int` instance and use the `Enum GF4` instance to
-- convert back and forth.
-- BUT note that, though this was the original question's spec for
-- (+), this is not how addition in GF4 is usually defined. Thanks
-- to chi for pointing it out. Presumably the definition for x - y
-- below also needs to be updated; perhaps defining negate instead
-- would involve less repetition.
x + y = toEnum ((fromEnum x + fromEnum y) `mod` 4)
GF4_0 * y = 0
GF4_1 * y = y
GF4_2 * GF4_2 = GF4_3
-- etc.
-- and a couple other bookkeeping functions; see :info Num or the haddocks
x - y = toEnum ((fromEnum x - fromEnum y) `mod` 4)
fromInteger n = toEnum (fromInteger (n `mod` 4))
abs = id
signum = toEnum . signum . fromEnum
Now you can try it out in ghci:
> (3 * 2 :: GF4) == (1 :: GF4)
True
Another option that makes the Num instance less tedious is to explicitly represent it as a polynomial with mod-2 coefficients. I'll pull a silly trick I've pulled a few times before to treat Bool as mod-2 numbers (with False representing 0 and True representing 1):
instance Num Bool where
(+) = (/=)
(*) = (&&)
negate = not
abs = id
signum = id
fromInteger = odd
(An aside for the Haskell experts: if the orphan instance makes you queasy, feel free to define data Bit = O | I and write out the Num instance a bit more explicitly.)
Now we define GF4 to have two fields ("fields" in the programming sense, not the number theory sense):
data GF4 = Bool :×+ Bool deriving (Eq, {- Ord, maybe? -} Read, Show)
The ×+ is supposed to be a bit of a visual pun: we'll represent ax + b as a:×+b. Now the (corrected) Num instance looks quite a bit more ordered:
instance Num GF4 where
(a:×+b) + (a':×+b') = (a + a'):×+(b + b')
(a:×+b) * (a':×+b') = (a*a' + a*b' + b*a'):×+(a*a' + b*b')
negate = id
abs = id
signum (a:×+b) = 0:×+(a*b)
fromInteger n = 0:×+fromInteger n
x :: GF4
x = 1:×+0
Unlike the previous instance, not all inhabitants of this GF4 are available as literal numbers -- only the constant polynomials. So we define an extra value, x, to give access to the non-constant polynomials. (Or you can use the constructor directly.) Now we can try out your example in ghci; what you call 2 I call x, and what you call 3 I call x+1.
> (x+1) * x == 1
True
As #WillemVanOnsem says in the comments, GF4 should be a data type, rather than a typeclass. Despite the name, they are totally different things! A typeclass is a collection of functions which are general enough that they can have similar implementations for multiple different types; a data type is nearly the reverse, in that it defines a totally new type which the users may use as they wish.
So how do you define GF4 as a data type? The ‘simplest’ way (for one definition of ‘simplest’) is to simply define it as a wrapper around Int:
newtype GF4 = GF4 Int
(Quick note: in case you haven’t run into them before, newtypes are a special kind of data type; they are used when you want to give a new name to another type by wrapping it. See e.g. LYAH for the difference between newtypes and datas.)
Now, note that (+) and (*) are members of the Num typeclass — this makes sense, since you can implement those functions for a wide range of types — so now you can write a Num instance:
instance Num GF4 where
(+) (GF4 x) (GF4 y) = GF4 ((x + y) `mod` 4)
(*) (GF4 0) (GF4 y) = GF4 0
(*) (GF4 1) (GF4 y) = GF4 y
-- and so on and so forth
-- but Num also has some other functions; let’s implement those too
negate (GF 0) = GF 0
negate (GF 1) = (GF 3)
negate (GF 2) = GF 2
-- note that a ‘negate’ implementation automatically gives you (-) as well
abs x = x
signum x = x
-- this is an unsafe function — usually you’d avoid them, but it’s the
-- only way to implement this one
fromInteger x = if 0 <= x && x < 4 then GF (fromInteger x) else error "value out of bounds!"
Then, you can export the name of the type GF4, but not the constructor GF4 :: Int -> GF4; thus outside people can use your type, but cannot construct invalid values like GF4 30.
Yet there is a better way. Note that GF4 only has four values — so it’s totally feasible to define this as an enumeration:
data GF4 = GF0 | GF1 | GF2 | GF3
This way, you can export everything, and still have it impossible by design to construct invalid values. This is considered good practice in Haskell; for this reason alone, I would use this definition rather than the newtype one. The implementation of Num is very similar to that given above; for this reason I won’t write the whole thing out again, but you should be able to easily figure it out.
You need to specify a type in our instance declaration. E.g.
instance GF4 Int where
0 + 0 = 0
2 * 3 = 1
To use it you still need to hide (+) and (*) from Prelude:
import Prelude hiding ((*), (+))
Now you can start using your GF4 instance:
one :: Int
one = 2 * 3

Haskell: why is failing with equals symbols?

I'm having an issue that is frustrating me a bit. I have the next really simple code:
describe "functions" $ do
it "can create a function" $ do
mysum :: a -> a
let mysum x = x + 1
mysum 5
But is not compiling, the error I'm having is:
error: Variable not in scope: mysum :: a -> a
|
15 | mysum :: a -> a
From the books I'm reading seems everything fine to me, and in internet seems that shouldn't fail my code, am I missing something?
Also I tried more alternatives:
let b = mysum :: a -> a
let b x = x + 1
b 5
And
let b = a -> a
let b x = x + 1
b 5
But in all of them I have errors
To define a function with a signature in a do-block, you need to put both its signature and its definition inside the same let. Indentation matters. For instance,
example = do
something1
something2
let mysum :: Num a => a -> a
mysum x = x + 1 -- same indentation as "mysum" above
something3 -- we can use mysum here
something4
Concretely:
describe "functions" $ do
it "can create a function" $ do
let mysum :: Num a => a -> a
mysum x = x + 1
mysum 5 `shouldBe` (6 :: Int)
The above declares a polymorphic mysum, as you tried to do. If we instead define a more basic mysum :: Int -> Int, we do not need to specify that 6 is an Int in the very last line, since that's already deduced.

Haskell function to check if two values are identical

In Haskell we have the function (==) :: Eq a => a->a->Bool which is fine for the large number of datatypes for which an instance of Eq can be defined. However there are some types for which there is no reasonable way to define an instance of Eq. one example is the simple function type (a->b)
I am looking for a function that will tell me if two values are actually the same -- not equal but identical.
For example f(id,id) ==> True f((+),(-)) = False
Clarification:
I don't want to know if two function do the same thing. It is not possible in the general case to do so. I want to know if I've gotten back the same thing I started with. Let me give a stripped down example:
data Foo = Foo (Foo->Foo) --contains a function so no Eq instance
x :: Foo
x = Foo id -- or for that matter Foo undefined
y :: Foo
y = Foo (const x)
a :: Foo
a = let (Foo fy) = y
in fy x
It is clear that by inspection once evaluated, a will be x. But let's assume I don't know the function in y but I want to test if the Foo I put in is the same one I got back - that is does fy x give me x. How do I do this?
One way that wasn't mentioned in Pointer equality in Haskell? is reallyUnsafePtrEquality#. As the name suggests it can be unpredictable and probably should't be used but it can be interesting to see how ghc works. Here's how you can use it in ghci:
> :set -package ghc-prim
> import GHC.Prim
> import GHC.Types
> isTrue# (reallyUnsafePtrEquality# id id)
True
> let a x = x + 2 :: Int
> isTrue# (reallyUnsafePtrEquality# a a)
True
> let b x = x + 2 :: Int
> isTrue# (reallyUnsafePtrEquality# a b)
False
If the function isn't monomorphic it doesn't work:
> let c x = x + 2
> isTrue# (reallyUnsafePtrEquality# c c)
False
Some more examples:
> let d = c in isTrue# (reallyUnsafePtrEquality# d d)
False
> :set -XMonomorphismRestriction
> let d = c in isTrue# (reallyUnsafePtrEquality# d d)
True
You can compare polymorphic types if you wrap them in a newtype:
> :set -XRankNTypes
> newtype X = X (forall a. Num a => a -> a)
> let d = X c
> isTrue# (reallyUnsafePtrEquality# d d)
True
Applying anything makes them not equal
> isTrue# (reallyUnsafePtrEquality# (id ()) (id ()))
False
But when compiling with optimisations this is True.
Hopefully this is enough to convince you that what you want is a bad idea. One of the solutions in Pointer equality in Haskell? would be a better.

Memoization not function correctly

I have the following code:
pB :: [(Integer, Integer, Integer)] -> Integer -> Integer -> [(Integer, Integer, Integer)]
pB lst x y
| screenList lst x y /= -1 = lst
| abs x > y = lst++[(x, y, 0)]
| y == 1 = lst++[(x, y, 1)]
| otherwise = lst++newEls
where
newEls = (pB lst x (y-1))++(pB lst (x-1) (y-1))++(pB lst (x+1) (y-1))
getFirst :: (Integer, Integer, Integer) -> Integer
getFirst (x, _, _) = x
getSecond :: (Integer, Integer, Integer) -> Integer
getSecond (_, y, _) = y
getThird :: (Integer, Integer, Integer) -> Integer
getThird (_, _, z) = z
screenList :: [(Integer, Integer, Integer)] -> Integer -> Integer -> Integer
screenList [] _ _ = -1
screenList lst x y
| getFirst leader == x && getSecond leader == y = getThird leader
| otherwise = screenList (tail lst) x y
where
leader = head lst
Which, by running an inefficient solution of (Ie: One which didn't keep track of values which had already been computed) returned the value 51 for input x = 0, y = 5. Now, running this with input [] 0 5 I should be able to find (0,5,51) in the output, which unfortunately I don't.
I have been looking at it for a few hours, but can't seem to understand where I'm going wrong.
Does anybody have any suggestions?
EDIT: Inefficient version:
nPB :: Integer -> Integer -> Integer
nPB x y
| abs x > y = 0
| y == 1 = 1
| otherwise = (nPB x (y-1)) + (nPB (x-1) (y-1)) + (nPB (x+1) (y-1))
Administrivia
It is rather hard to tell what you are asking, but I gather that you have a function that is terribly slow and you have tried to manually memoize this function. I don't think anyone is trying to understand your attempt, so if this question is primarily about manually memoizing a function and/or fixing your code then please submit another question that more clearly outlines its design.
In the remainder of this question I will show you how to use monad-memo and memo-trie to memoize the function you've named nPB.
Memoizing nPB with monad-memo
The nPB function is a prime target for memoization. This is readily apparent by glancing at it's three recursive calls. The below small benchmark takes 1 second to run, lets see if we can do better.
nPB :: Integer -> Integer -> Integer
nPB x y
| abs x > y = 0
| y == 1 = 1
| otherwise = (nPB x (y-1)) + (nPB (x-1) (y-1)) + (nPB (x+1) (y-1))
main = print (nPB 10 20)
In a previous answer I used the monad-memo package. Using monad-memo involves making your function monadic, which is syntactically more invasive than the other packages I know of, but I've always have good performance.
To use the package you simply:
make sure to call one of the memo functions with the target function as the first parameter.
Be sure to return your final result
Adjust your type signatures to include a constraint of MonadMemo and adjust the result to be some monad m.
Run the function with startEvalMemo
The code is:
{-# LANGUAGE FlexibleContexts #-}
import Control.Monad.Memo
nPB :: (MonadMemo (Integer,Integer) Integer m) => Integer -> Integer -> m Integer
nPB x y
| abs x > y = return 0
| y == 1 = return 1
| otherwise = do
t1 <- for2 memo nPB x (y-1)
t2 <- for2 memo nPB (x-1) (y-1)
t3 <- for2 memo nPB (x+1) (y-1)
return (t1+t2+t3)
main = print (startEvalMemo $ nPB 10 20)
Memoizing nPB with MemoTrie
The most common Haskell memoization package in use is MemoTrie. This is also a syntactically cleaner memoization package as it does not requires any sort of monad, but it currently suffers from a slight performance issue when using Integer as we shall soon see (bug has been reported, use of Int and other types seems fine).
There is much less to do to use MemoTrie, just replace your recursive calls with memoN where N is the number of arguments:
import Data.MemoTrie
nPB :: Integer -> Integer -> Integer
nPB x y
| abs x > y = 0
| y == 1 = 1
| otherwise = (memo2 nPB x (y-1)) + (memo2 nPB (x-1) (y-1)) + (memo2 nPB (x+1) (y-1))
main = print (nPB 10 20)
Performance
Using a type of Integer the performance is:
$ ghc original.hs -O2 && time ./original
8533660
real 0m1.047s
$ ghc monad-memo.hs -O2 && time ./monad-memo
8533660
real 0m0.002s
$ ghc memotrie.hs -O2 && time ./memotrie
8533660
real 0m0.331s
And using Int:
$ ghc original.hs -O2 && time ./original
8533660
real 0m0.190s
$ ghc monad-memo.hs -O2 && time ./monad-memo
8533660
real 0m0.002s
$ ghc memotrie.hs -O2 && time ./memotrie
8533660
real 0m0.002s
I guess this question is about memoization. I'm not sure how you are trying to implement this, but there are two "standard" ways of memoizing functions: use one of the libraries, or explicitly memoize the data yourself.
import Data.Function.Memoize (memoize)
import Data.MemoTrie (memo2)
import Data.Map (fromList, (!))
import System.Environment
test0 :: Integer -> Integer -> Integer
test0 x y
| abs x > y = 0
| y == 1 = 1
| otherwise = (test0 x (y-1)) + (test0 (x-1) (y-1)) + (test0 (x+1) (y-1))
test1 :: Integer -> Integer -> Integer
test1 = memoize test0
test2 :: Integer -> Integer -> Integer
test2 = memo2 test0
But it doesn't look like the memo libraries I tried are able to handle this, or I did something wrong, I've never really used these libraries: (The test code is at the bottom - these results from x,y = 0,18)
test0 : Total time 9.06s
test1 : Total time 9.08s
test2 : Total time 32.78s
So lets try manual memoization. The principle is simple: construct your domain in such a way that later elements only require the value of earlier elements. This is very simple here since your function always recurses on y-1, so you just need to build the domain moving up the rows. Then write a function which looks up earlier values in a table (here I use Data.Map.Map), and map over the domain:
test3 :: Integer -> Integer -> Integer
test3 x' y' = m ! (x', y')
where
xs = concat [ map (flip (,) y) [-x + x' .. x + x'] | (x, y) <- zip [y', y' - 1 .. 1] [1..]]
m = fromList [ ((x,y), go x y) | (x,y) <- xs]
go x y
| abs x > y = 0
| y == 1 = 1
| otherwise = m ! (x, y-1) + m ! (x-1, y-1) + m ! (x+1, y-1)
I actually construct a domain that is much than needed for simplicity, but the performance penalty is small since the extra domain is all 0 anyways. Taking a look at the performance, it is almost instant (Total time 0.02s). Even with x,y=0,1000 it still only takes 7 seconds. Although with large inputs you end up wasting a lot of time on GC.
-- usage: ghc --make -O2 -rtsopts Main.hs && Main n x y +RTS -sstderr
main = do
[n, x, y] <- getArgs
print $ (d !! (read n)) x y
where d = [test0, test1, test2, test3]
Here is the version written with memoFix2. Better performance than any other versions.
test4 :: Integer -> Integer -> Integer
test4 = memoFix2 go where
go r x y
| abs x > y = 0
| y == 1 = 1
| otherwise = (r x (y-1)) + (r (x-1) (y-1)) + (r (x+1) (y-1))

Strange pattern matching with functions instancing Show

So I'm writing a program which returns a procedure for some given arithmetic problem, so I wanted to instance a couple of functions to Show so that I can print the same expression I evaluate when I test. The trouble is that the given code matches (-) to the first line when it should fall to the second.
{-# OPTIONS_GHC -XFlexibleInstances #-}
instance Show (t -> t-> t) where
show (+) = "plus"
show (-) = "minus"
main = print [(+),(-)]
returns
[plus,plus]
Am I just committing a mortal sin printing functions in the first place or is there some way I can get it to match properly?
edit:I realise I am getting the following warning:
Warning: Pattern match(es) are overlapped
In the definition of `show': show - = ...
I still don't know why it overlaps, or how to stop it.
As sepp2k and MtnViewMark said, you can't pattern match on the value of identifiers, only on constructors and, in some cases, implicit equality checks. So, your instance is binding any argument to the identifier, in the process shadowing the external definition of (+). Unfortunately, this means that what you're trying to do won't and can't ever work.
A typical solution to what you want to accomplish is to define an "arithmetic expression" algebraic data type, with an appropriate show instance. Note that you can make your expression type itself an instance of Num, with numeric literals wrapped in a "Literal" constructor, and operations like (+) returning their arguments combined with a constructor for the operation. Here's a quick, incomplete example:
data Expression a = Literal a
| Sum (Expression a) (Expression a)
| Product (Expression a) (Expression a)
deriving (Eq, Ord, Show)
instance (Num a) => Num (Expression a) where
x + y = Sum x y
x * y = Product x y
fromInteger x = Literal (fromInteger x)
evaluate (Literal x) = x
evaluate (Sum x y) = evaluate x + evaluate y
evaluate (Product x y) = evaluate x * evaluate y
integer :: Integer
integer = (1 + 2) * 3 + 4
expr :: Expression Integer
expr = (1 + 2) * 3 + 4
Trying it out in GHCi:
> integer
13
> evaluate expr
13
> expr
Sum (Product (Sum (Literal 1) (Literal 2)) (Literal 3)) (Literal 4)
Here's a way to think about this. Consider:
answer = 42
magic = 3
specialName :: Int -> String
specialName answer = "the answer to the ultimate question"
specialName magic = "the magic number"
specialName x = "just plain ol' " ++ show x
Can you see why this won't work? answer in the pattern match is a variable, distinct from answer at the outer scope. So instead, you'd have to write this like:
answer = 42
magic = 3
specialName :: Int -> String
specialName x | x == answer = "the answer to the ultimate question"
specialName x | x == magic = "the magic number"
specialName x = "just plain ol' " ++ show x
In fact, this is just what is going on when you write constants in a pattern. That is:
digitName :: Bool -> String
digitName 0 = "zero"
digitName 1 = "one"
digitName _ = "math is hard"
gets converted by the compiler to something equivalent to:
digitName :: Bool -> String
digitName x | x == 0 = "zero"
digitName x | x == 1 = "one"
digitName _ = "math is hard"
Since you want to match against the function bound to (+) rather than just bind anything to the symbol (+), you'd need to write your code as:
instance Show (t -> t-> t) where
show f | f == (+) = "plus"
show f | f == (-) = "minus"
But, this would require that functions were comparable for equality. And that is an undecidable problem in general.
You might counter that you are just asking the run-time system to compare function pointers, but at the language level, the Haskell programmer doesn't have access to pointers. In other words, you can't manipulate references to values in Haskell(*), only values themselves. This is the purity of Haskell, and gains referential transparency.
(*) MVars and other such objects in the IO monad are another matter, but their existence doesn't invalidate the point.
It overlaps because it treats (+) simply as a variable, meaning on the RHS the identifier + will be bound to the function you called show on.
There is no way to pattern match on functions the way you want.
Solved it myself with a mega hack.
instance (Num t) => Show (t -> t-> t) where
show op =
case (op 6 2) of
8 -> "plus"
4 -> "minus"
12 -> "times"
3 -> "divided"

Resources