Error: not in scope. Why this is happening? - haskell

i need to define an instance for the class Enum based on the datatype Int'. I just need to define the functions toEnum and fromEnum.
For example: map fromEnum [Minus One .. Plus (Succ’ One)] -> [-1,0,1,2]
data PosNat = One | Succ' PosNat
data Int' = Zero' | Plus PosNat | Minus PosNat
instance Enum Int' where
toEnum 0 = Zero'
toEnum n | n>0 = Plus (toPosNat n )
toEnum n | n<0 = undefined -- Minus (toPosNat n)
where
toPosNat :: a -> PosNat
toPosNat 1 = One
toPosNat n | n>1 = (Succ' (toPosNat (n-1)) )
toPosNat n | n<1 = (Succ' (toPosNat (n+1)) )
The problem is, i get following error:
Variable not in scope: toPosNat :: Int -> PosNat
|
62 | toEnum n | n>0 = Plus (toPosNat n )
|
Thanks for your help! :)

A where clause attaches to all of the guards of a single pattern. You've defined your function using three separate patterns, so the where clause only attaches to the last of them. To fix this, simply roll the last two patterns (which are the same, minus the guards) together:
instance Enum Int' where
toEnum 0 = Zero'
toEnum n | n>0 = Plus (toPosNat n )
| n<0 = Minus (toPosNat n)
where
toPosNat :: a -> PosNat
toPosNat 1 = One
toPosNat n | n>1 = (Succ' (toPosNat (n-1)))
| n<1 = (Succ' (toPosNat (n+1)))
I've made the same change to toPosNat because this is better style, but it has no semantic impact in this case.

You need to promote toPosNat to a top-level function, like this:
instance Enum Int' where
toEnum 0 = Zero'
toEnum n | n>0 = Plus (toPosNat n )
toEnum n | n<0 = undefined -- Minus (toPosNat n)
toPosNat :: a -> PosNat
toPosNat 1 = One
toPosNat n | n>1 = (Succ' (toPosNat (n-1)) )
toPosNat n | n<1 = (Succ' (toPosNat (n+1)) )
The where clause that you have in your code is only visible in the third case, not in the second case.

Related

How can I define an infinite / looped algebraic datatype in haskell?

I have a music note datatype defined like so:
data Note = Ab | A | Bb | B | C | Db | D | Eb | E | F | Gb | G deriving (Eq, Ord)
How can i make it an instace of Enum so that succ G returns Ab ?
You have to define the Enum instance yourself:
instance Enum Note where
fromEnum note = case note of
Ab -> 0
A -> 1
...
toEnum n = case n `mod` 12 of
0 -> Ab
1 -> A
...
The "modulo 12" part in toEnum will cycle your notes.

Modifying a list using recursion

I have a list with elements of type LocalType (defined below), I wish to modify this list in function of which subtptype the element is belonging too.
An element of type End stays in the list of type End. For an element of type Prl (End Bar End), the first End shall stay in the list, the second End shall be appended to the list.
E.g [End, (Prl s Bar ss)] -> [End, s, ss]
E.g [End, End Bar End] -> [End, End, End]
This is how I thought of implementing it,
sepTimes :: [LocalType] -> [LocalType]
sepTimes(x:[]) = [x]
sepTimes(x:xs)
| x == End = sepTimes (x:xs)
| x == (Prl s Bar ss) = do
sepTimes (s:xs)
sepTimes (ss:xs)
As the error messages states, I am unable to retrive the elements s and ss corresponding to End and End in the example of Prl (End Bar End).
app\Sequents.hs:44:17: error: Variable not in scope: s :: LocalType
|
44 | | x == (Prl s Bar ss) = do
| ^
app\Sequents.hs:44:23: error:
* Variable not in scope: ss :: LocalType
* Perhaps you meant `xs' (line 42)
|
44 | | x == (Prl s Bar ss) = do
| ^^
app\Sequents.hs:45:19: error: Variable not in scope: s :: LocalType
|
45 | sepTimes (s:xs)
| ^
app\Sequents.hs:46:19: error:
* Variable not in scope: ss :: LocalType
* Perhaps you meant `xs' (line 42)
|
46 | sepTimes (ss:xs)
| ^^
Here are the defined datatypes :
data Seperator = Bar | BackAmpersand
deriving (Show, Eq, Ord, Read)
data LocalType = End
| Prl LocalType Seperator LocalType
deriving (Eq, Ord, Read)
You're confusing equality checks with pattern matching. Intuitively, all of the following should be the same:
f :: Either Int Char -> String
f (Left i) = show i
f (Right c) = [c]
f :: Either Int Char -> String
f x = case x of
Left i -> show i
Right c -> [c]
f :: Either Int Char -> String
f x
| x==Left i = show i -- what?
| x==Right c = [c]
But actually, only the first two are equivalent, the last one doesn't work. Why? You can't match a variable out of an equality statement. That may work in some logical languages where the equality is propositional, but Haskell's == operator is simply boolean: it takes two fully known values and tells you whether or not they're exactly the same. I.e., in order to be able to write x==Left i, the variable i must already be defined.

Haskell scripts to solve identity matrix

how to solve identity for a matrix using Haskell scripts?
For example, if with this given type
type Matrice a = [[a]]
identity :: Int -> Maybe (Matrice Int)
How can it return the identity matrice for the given size? I know that identity matrice is a square matrice which has zero for all values, except the values on the top-left to bottom-right diagonal which are all one. With the condition of, if the size is less than 1, then the identity matrice isn't defined and Nothing is returned.
So say for example,
Prelude > identity 5
Just [[1,0,0,0,0],[0,1,0,0,0],[0,0,1,0,0],[0,0,0,1,0],[0,0,0,0,1]]
Prelude > identity 2
Just [[1,0],[0,1]]
I've tried
identity1 :: Int -> Int -> [Int]
identity1 a b
| a == 0 []
| b == 0 (1:identity (a-1) (-1))
| otherwise = (0:identity' (a-1) (b-1))
identity2 :: Int -> Int -> Matrice Int
identity2 a b
| b == 0 []
| otherwise = (0:identity1 (a-1) (b-1) : identity2 a (b-1)
One short approach is to define the "infinite" identity matrix as
ii = (1 : repeat 0) : fmap (0:) ii
The first row is 1 0 0 ...; each subsequent row is the row above it with a 0 prepended to it.
It should be obvious that the first n rows of the first n columns of the infinite identity matrix is In.
1 | 0 | 0 | 0 | 0 | 0 |
--+ | | | | |
0 1 | 0 | 0 | 0 | 0 |
------+ | | | |
0 0 1 | 0 | 0 | 0 |
----------+ | | | ...
0 0 0 1 | 0 | 0 |
--------------+ | |
0 0 0 0 1 | 0 |
------------------+ |
0 0 0 0 0 1 |
----------------------+
. .
. .
. .
Given that, we just use take to obtain the appropriate-sized sub matrix. take n applied to each row will return the first n columns, and take n applied to the result takes just the first n rows.
type Matrix a = [[a]]
identity :: Int -> Maybe (Matrix Int)
identity n | n <= 0 = Nothing
| otherwise = let ii = (1:repeat 0) : (fmap (0:) ii)
in Just $ take n (take n <$> ii)
If recursively defined infinite lists tie your brain in knots, you can also just define an enlarge function that generates In+1 from In. To do so, it is convenient to assume that I0 exists and is represented as an empty list.
enlarge :: Matrix Int -> Matrix Int
enlarge [] = [[1]]
enlarge i#(r:_) = (1:(0<$r)) : fmap (0:) i
Then you can define identity :: Int -> Matrix Int by indexing an infinite list of identity matrices
identity n | n <= 0 = Nothing
identity n = Just (identities !! n)
where identities :: [Matrix Int] is built with either iterate
identities = iterate enlarge []
or Data.List.unfoldr:
identities = unfoldr (\x -> Just (x, enlarge x)) []
It's also worth noting that the infinite identity matrix is the fixed point of enlarge:
import Data.Function
ii = fix enlarge
One way to accomplish this is through recursion.
I'm going to ask you some leading questions, since I haven't seen what you've tried so far:
What's the identity for 1x1 matrices?
Given the identity for nxn matrices, what would you need to add to create the identity for (n+1)x(n+1) matrices?
Or in pseudo-code:
identity 1 = Just $ _1x1_identity
-- _1x1_identity :: [[Int]]
identity n_plus_1 | n_plus_1 > 1 = fmap _alter_identity (identity n)
where n = n_plus_1 - 1
-- _alter_identity :: [[Int]] -> [[Int]]
identity n | n < 1 = Nothing
If you're unfamiliar with fmap, it's used here to unwrap/rewrap the Maybe value returned from the other call to identity.
I could do the same more verbosely as
identity n_plus_1 | n_plus_1 > 1 = case identity n of
Nothing -> Nothing
Just matrix -> Just (_alter_identity matrix)
where n = n_plus_1 - 1
Your approach in the comments attempts to construct the entire matrix row by row, which is also workable.
One way to implement that approach more directly is through a list comprehension.
List comprehensions make it easy to define new lists and lists of lists:
Prelude> [ i | i <- [0..4] ]
[0,1,2,3,4]
Prelude> [ [(i,j) | j <- [0..3]] | i <- [0..2] ]
[ [(0,0),(0,1),(0,2),(0,3)]
, [(1,0),(1,1),(1,2),(1,3)]
, [(2,0),(2,1),(2,2),(2,3)]
]
Above we can see that we can use a list comprehension to generate a matrix of coordinates - the value (i,j) shows up in the i'th row and the jth column.
List comprehensions allow you to place arbitrary expressions on the left-hand-side of the |, so I could do i + j instead of (i,j) to get a very different matrix:
Prelude> [ [i + j | j <- [0..3]] | i <- [0..2] ]
[ [0,1,2,3]
, [1,2,3,4]
, [2,3,4,5]
]
That's a rectangular matrix. A square matrix would use the same bounds for i and j.
If you were to use a list comprehension like that to create a square matrix, what expression would you put to the left hand side of the | to create the identity matrix? To put it another way, can you express the identity matrix's value at row i column j in terms of i and j?
In case one needs some iterative approach in Haskell, recursion is used. This means that we need to define base case(s) as well as inductive case(s).
There are two base cases here:
the value is less than or equal to zero, in that case the value is Nothing;
the case where the value is exactly one, in that case we return a Just with a 1×1 matrix:
1
There is one inductive case: in case the number is greater than 1, we first generate the identity matrix for n-1, and then we add row at the top and a column at the left:
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
this means we thus need to prepend all rows of the previous matrix with 0, and we prepend the matrix with a list that contains one 1 and n-1 zeros.
Let us first forget about the first base case (n is less than or equal to zero), and assume n is always strictly positive. In that case there is no need to wrap the value in a Maybe, so we first construct a function:
identity' :: Int -> Matrix Int
identity' = ...
so the base case is where the parameter is 1:
identity' 1 = ...
and the inductive case has shape:
identity' n = first_row : map prepend_zero (identity (n-1))
where first_row = ...
prepend_zero = ...
Now we can construct identity in terms of identity' by only once check whether the value is less than or equal to zero:
identity :: Int -> Maybe (Matrix Int)
identity n | n <= 0 = Nothing
| otherwise = Just (identity' n)
where identity' 1 = ...
identity' n = first_row : map prepend_zero (identity (n-1))
where first_row = ...
prepend_zero = ...
I leave the expressions (...) as an exercise that should probably be reasonable.
deconstructivism
identity n = splitEvery n $ (concat $ replicate (n-1) $ 1: replicate n 0)++[1]
proof without words
[[1,0,0,0,0],[0,1,0,0,0],[0,0,1,0,0],[0,0,0,1,0],[0,0,0,0,1]] ~
[1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1] ~
[1,0,0,0,0,0],[1,0,0,0,0,0],[1,0,0,0,0,0],[1,0,0,0,0,0] ++ [1] ~
[1,0,0,0,0,0]{4} ++ [1] ~
(1:[0]{5}){4} ++ [1]
you need to handle special cases (n<0 and n==1)

An haskell "exp" function returns a wrong result

the following code:
Module Main where
main :: IO ()
main = do putStrLn "hello"
putStrLn $ "2 exp 6 = " ++ show (2 `exp1` 6)
exp1 :: Integer -> Integer -> Integer
exp1 x n | n == 0 = 1
| n == 1 = x
| even n = exp1 (x*x) m
| odd n = x * exp1 (x*x) (m-1)
where m = n `div` 2
produces the output 4 for 2 `exp1` 6, which is obviously wrong.
thanks
The odd case is wrong. You end up evaluating exp1 4 3 to be 4 * (exp1 16 0).

recursive haskell function hangs forever in interactive session

I have a recursive function that plots some picture in ASCII art. It is quite simple being
type Picture = [[Char]]
white :: Picture
white = ["......",
"......",
"......",
"......",
"......",
"......"]
black = ["######",
"######",
"######",
"######",
"######",
"######"]
printPicture :: Picture -> IO ()
printPicture = putStr . concat . map (++"\n")
With these blocks I want to construct a game board. I have define some functions to do so, which are:
blackinWhite :: Integer -> Integer -> Picture
blackinWhite n m | n==1 && m==1 = black
| n==1 = white
| n==m = black `beside` blackinWhite (n-1) m
| otherwise = white `beside` blackinWhite (n-1) m
blackinWhite' :: Integer -> Integer -> Picture
blackinWhite' n m | n==1 && m==1 = black
| n==1 = white
| n==m = black `above` blackinWhite' (n-1) m
| otherwise = white `above` blackinWhite' (n-1) m
diagonalrug :: Integer -> Integer -> Picture
diagonalrug n m | m==1 = blackinWhite n m
| otherwise = blackinWhite n m `above` diagonalrug n (m-1)
antidiagrug :: Integer -> Integer -> Picture
antidiagrug n m | m==1 = blackinWhite' n m
| otherwise = antidiagrug n (m-1) `beside` blackinWhite' n m
crossedrug :: Integer -> Integer -> Picture
crossedrug n m | dimn /= 0 || dimm /= 0= error("Come back later")
| otherwise = diagonalrug dimn dimm --((diagonalrug dimn dimm) `beside` (antidiagrug dimn dimm)) `above` ((antidiagrug dimn dimm) `beside` (diagonalrug dimn dimm))
where
dimn = mod n 2
dimm = mod m 2
If I do in the interactive session:
*Main> diagonalrug 2 2
The program hangs and my computer is freezed. If I execute directly the statement that comes after otherwise, the result is given without any problems. Why if I call the function crossedrug ghci crashes?
(I am not providing the functions above and beside, since they simply concatenate two pictures that should be clear from the context.)
Just follow execution.
You're calling it with 2 2, it goes to the otherwise and calls diagonalrug 0 0 which in turn goes to the otherwise clause which never terminates since it calls diagonalrug 0 -1 so m is never 1 (it keeps being negative).
diagonalrug is missing a stopping condition for that case.

Resources