I do not understand this error haskell - haskell

My code receives a list of values ​​in hexadecimal and i have to pass them to binary and put each result in a list but I have these two errors and i dont know how to fix them
Pixels.hs:121:29:
Occurs check: cannot construct the infinite type:
t0 = Bool -> [a1] -> t0
In the return type of a call of `modA'
Probable cause: `modA' is applied to too many arguments
In the expression:
modA (o ++ [(k `mod` 2)]) (l + 1) (k `div` 2) otherwise o
In an equation for `modA':
modA o l k
| l < 8 = modA (o ++ [(k `mod` 2)]) (l + 1) (k `div` 2) otherwise o
Pixels.hs:126:89:
Couldn't match expected type `[a0]'
with actual type `Bool -> t1 -> [[a1]] -> [a0] -> t0'
In the first argument of `(++)', namely `f'
In the fourth argument of `f', namely
`(f
++
[(psr (head (e1)))
++
(psr (head (e2)))
++ (psr (head (e3))) ++ (psr (head (e4))) ++ (psr (head (e5)))])'
In the expression:
f otherwise
convertir
[tail (e1), tail (e2), tail (e3), tail (e4), ....]
(f
++
[(psr (head (e1)))
++
(psr (head (e2)))
++ (psr (head (e3))) ++ (psr (head (e4))) ++ (psr (head (e5)))])
Failed, modules loaded: none.
here is the code
rInt :: String -> Int
rInt = read
font:: Char -> Pixels
font a = let x= ord a in
if x>=0 || x<=31 || x>=126 then ["*****","*****","*****","*****","*****","*****","*****"]
else
auxfont (fontBitmap!!(x-32))
where
auxfont b = let y = map trns (map rInt (map show b)) in
convertir y []
trns z = modA [] 1 z
modA o l k
| l < 8 = modA (o++[(k `mod` 2)]) (l+1) (k `div` 2)
otherwise o
convertir (e1:e2:e3:e4:e5) f
| null e1 = f
otherwise convertir [tail(e1),tail(e2),tail(e3),tail(e4),tail(e5)] (f++[(psr(head(e1)))++(psr(head(e2)))++(psr(head(e3)))++(psr(head(e4)))++(psr(head(e5)))])
psr 0 = " "
psr 1 = "*"

Your syntax is wrong, you need a | before otherwise:
foo x y z | x > y = ...
| otherwise = ...

Related

how to use type correctly in a function?

I am trying to write numerical methods for calculating the integral
module NumericalMethods(
trapezoidal_method
) where
type Func = Double -> Double
type Interval = [Double]
type N = Integer
trapezoidal_method:: Func -> Interval -> N -> Double
trapezoidal_method f interval n = h*((f (head interval) + f $ tail interval)/2 + sum_fxs)
where
h :: Double
h = (tail interval - head interval) / fromIntegral n
sum_fxs = sum fxs
fxs = map f [head interval + h * fromIntegral x | x <- [1..n-1]]
I get this error:
• Couldn't match expected type ‘Double -> Double’ with actual type ‘Double’
• Possible cause: ‘f’ is applied to too many arguments
In the first argument of ‘(+)’, namely ‘f (head interval)’
In the first argument of ‘($)’, namely ‘f (head interval) + f’
In the first argument of ‘(/)’, namely ‘(f (head interval) + f $ tail interval)’
|
10 | trapezoidal_method f interval n = h*((f (head interval) + f $ tail interval)/2 + sum_fxs)
| ^^^^^^^^^^^^^^^^^
One issue is your use of $ in f (head interval) + f $ tail interval.
The $ operator has the lowest precedence of almost everything, so it will be interpreted as (f (head interval) + f) $ (tail interval). It is trying to figure out what you mean with f (head interval) + f.
You probably just want to use parentheses: f (head interval) + f (tail interval).
A second issue is your use of lists for intervals. I think tuples would be more suitable:
type Interval = (Double, Double)
Then you can use fst and snd instead of the erroneous head and tail:
trapezoidal_method:: Func -> Interval -> N -> Double
trapezoidal_method f interval n = h*((f (fst interval) + f (snd interval))/2 + sum_fxs)
where
h :: Double
h = (snd interval - fst interval) / fromIntegral n
sum_fxs = sum fxs
fxs = map f [fst interval + h * fromIntegral x | x <- [1..n-1]]

Getting the error "Non type-variable argument in the constraint: Integral [a2]"

I'm trying to implement the luhn algorithm using the following code:
luhn :: Int -> Bool
luhn x = (tail $ show (foldl (\acc x -> acc + (read x :: Int)) 0 (foldr doEncrypt [] $ zip [0..] (show x)))) == "0"
where
doEncrypt (i,y) acc = if not(even i)
then head(((uncurry (+) . (`divMod` 10) . (*2)) y)) : acc
else (head y) : acc
I now got stuck with the following error:
• Non type-variable argument in the constraint: Integral [a2]
(Use FlexibleContexts to permit this)
• When checking the inferred type
doEncrypt :: forall a1 a2.
(Integral a1, Integral [a2]) =>
(a1, [a2]) -> [a2] -> [a2]
In an equation for ‘luhn’:
luhn x
= (tail
$ show
(foldl
(\ acc x -> acc + (read x :: Int))
0
(foldr doEncrypt [] $ zip [0 .. ] (show x))))
== "0"
where
doEncrypt (i, y) acc
= if not (even i) then
head (((uncurry (+) . (`divMod` 10) . (* 2)) y)) : acc
else
(head y) : acc
I see that the error suggests that the second part of the tuple (a2) is a "Non type-variable argument". However, Haskell seems to identify this a2 argument as an Integral while in fact it is a Char. How can I tell Haskell that this is a Char and that Haskell shouldn't worry any further about this variable's type? Or is there something else I'm not understanding which causes this error?
Edit:
When I remove the (head y) and replace it by y I get instead the following error:
• Couldn't match type ‘Char’ with ‘[Char]’
Expected type: [String]
Actual type: [Char]
• In the third argument of ‘foldl’, namely
‘(foldr doEncrypt [] $ zip [0 .. ] (show x))’
In the first argument of ‘show’, namely
‘(foldl
(\ acc x -> acc + (read x :: Int))
0
(foldr doEncrypt [] $ zip [0 .. ] (show x)))’
In the second argument of ‘($)’, namely
‘show
(foldl
(\ acc x -> acc + (read x :: Int))
0
(foldr doEncrypt [] $ zip [0 .. ] (show x)))’
There where multiple things wrong with my solution, but finally the following code works!
luhn :: Int -> Bool
luhn x = (tail $ show (foldl (\acc x -> acc + (digitToInt x)) 0 (foldr doEncrypt [] $ zip [0..] (show x)))) == "0"
where
doEncrypt (i,y) acc = if not(even i)
then (head $ show(((uncurry (+) . (`divMod` 10) . (*2)) (digitToInt y)))) : acc
else y : acc
Thanks a lot to #WillemVanOnsem for your pointers, without I probably wouldn't have solved this!

Maybe Int type error [duplicate]

This question already has answers here:
Operating on a return from a Maybe that contains "Just"
(2 answers)
Closed 5 years ago.
I'm getting a type error because I'm trying to recursively add a Maybe int int the function rankP seen bellow. Because the return type of rankP is Maybe Int, and the type of rankC is a tuple of Ints, it is telling me I cannot add Int with Maybe Int.
type Prog = [Cmd]
data Cmd = LD Int
| ADD
| MULT
| DUP
| INC
| SWAP
| POP Int
deriving Show
type Stack = [Int]
type D = Stack -> Maybe Stack
type Rank = Int
type CmdRank = (Int,Int)
rankC :: Cmd -> CmdRank
rankC (LD _) = (0,1)
rankC ADD = (2,1)
rankC MULT = (2,1)
rankC DUP = (1,2)
rankC INC = (1,1)
rankC SWAP = (2,2)
rankC (POP x) = (x,0)
rankP :: Prog -> Maybe Rank
rankP [] = Nothing
rankP [x] = Just (snd(rankC x) - fst(rankC x))
rankP (x:xs) = if ((Just (snd(rankC x) - fst(rankC x)) + rankP xs) < 0) then Nothing
else Just (snd(rankC x) - fst(rankC x)) + (rankP xs)
Here is the error I am receiving:
hw3.hs:43:64:
Couldn't match expected type `Int' with actual type `Maybe Rank'
In the return type of a call of `rankP'
In the first argument of `Just', namely `(rankP xs)'
In the second argument of `(+)', namely `Just (rankP xs)'
Failed, modules loaded: none.
I'm getting a slightly different error:
No instance for (Num (Maybe Int)) arising from a use of ‘+’
In the first argument of ‘(<)’, namely
‘(Just (snd (rankC x) - fst (rankC x)) + rankP xs)’
In the expression:
((Just (snd (rankC x) - fst (rankC x)) + rankP xs) < 0)
In the expression:
if ((Just (snd (rankC x) - fst (rankC x)) + rankP xs) < 0) then
Nothing
else
Just (snd (rankC x) - fst (rankC x)) + (rankP xs)
However, note that in
(Just (snd(rankC x) - fst(rankC x)) + rankP xs) < 0
you're trying to use + on two Maybe Rank objects, and compare the result with < to 0. Neither of these can work.
From your code, it looks like you're trying to "extract" the value of a Maybe Rank; see this question about that.
The problem is that you are attempting to do arithmetic with a Maybe Rank when you really need to extract the Rank from the Maybe Rank before doing any math. One way to do this is directly by hand:
rankP (x:xs) = if y == Nothing
then Nothing
else let Just y' = y in
if snd(rankC x) - fst(rankC x) + y' < 0
then Nothing
else Just (snd(rankC x) - fst(rankC x) + y')
where y = rankP xs
There are certainly more elegant ways to do this when you begin to understand the monadic properties of Maybe. I'm not there yet myself to give much help along those lines.

Trying to iterate over a forest Haskell compilation error

I try to assign to each node of a forest a number, such that there will be no 2 nodes with the same number. I try to use 2 functions which call eachother recursive but I get some compilation errors.
Here is the code :
numberTree :: Int -> Tree a -> (Tree Int,Int)
numberTree n (Node c []) = (Node n [], n+1)
numberTree n (Node _ (x:xs)) = (Node n fst.numberForest (n+1) xs, snd.numberForest (n+1) xs)
numberForest :: Int -> [Tree a] -> ([Tree Int],Int)
numberForest n (x:xs) = ((fst(numberTree n x )):(fst(numberForest (n+1) xs)), snd(numberForest (n+1) xs)+1)
numberForest n (x:xs) = ((fst(numberTree n x )):(fst(numberForest (n+1) xs)), snd(numberForest (n+1) xs)+1)
The errors I get are :
.hs:27:34:
Couldn't match expected type b0 -> c0' with actual typeTree Int
Possible cause: Node' is applied to too many arguments
In the first argument of(.)', namely `Node n fst'
In the expression: Node n fst . numberForest (n + 1) xs
.hs:27:34:
Couldn't match expected type `Tree Int' with actual type `a0 -> c0
In the expression: Node n fst . numberForest (n + 1) xs
In the expression:
(Node n fst . numberForest (n + 1) xs,
snd . numberForest (n + 1) xs)
In an equation for `numberTree':
numberTree n (Node _ (x : xs))
= (Node n fst . numberForest (n + 1) xs,
snd . numberForest (n + 1) xs)
.hs:27:42:
Couldn't match type `(a1, b1) -> a1' with `[Tree Int]'
Expected type: Forest Int
Actual type: (a1, b1) -> a1
Probable cause: `fst' is applied to too few arguments
In the second argument of `Node', namely `fst'
In the first argument of `(.)', namely `Node n fst'
.hs:27:46:
Couldn't match expected type `a0 -> b0'
with actual type `([Tree Int], Int)'
Possible cause: `numberForest' is applied to too many arguments
In the second argument of `(.)', namely `numberForest (n + 1) xs'
In the expression: Node n fst . numberForest (n + 1) xs
.hs:27:70:
Couldn't match expected type `Int' with actual type `a2 -> c1'
In the expression: snd . numberForest (n + 1) xs
In the expression:
(Node n fst . numberForest (n + 1) xs,
snd . numberForest (n + 1) xs)
In an equation for `numberTree':
numberTree n (Node _ (x : xs))
= (Node n fst . numberForest (n + 1) xs,
snd . numberForest (n + 1) xs)
.hs:27:74:
Couldn't match expected type `a2 -> (a3, c1)'
with actual type `([Tree Int], Int)'
Possible cause: `numberForest' is applied to too many arguments
In the second argument of `(.)', namely `numberForest (n + 1) xs'
In the expression: snd . numberForest (n + 1) xs
What is wrong and how should I solve this ?
This line
numberTree n (Node _ (x:xs)) = (Node n fst.numberForest (n+1) xs, snd.numberForest (n+1) xs)
actually means
numberTree n (Node _ (x:xs)) = ( (Node n fst) . (numberForest (n+1) xs)
, snd . (numberForest (n+1) xs))
which tries to compose trees instead of functions, causing the compiler to complain. You probably want something like this:
numberTree n (Node _ (x:xs)) = ( Node n (fst (numberForest (n+1) xs))
, snd (numberForest (n+1) xs))
However, be careful that the code above is computing numberForest (n+1) xs twice, causing an exponential blowup. You can avoid that e.g. using a let ... in ... as follows
numberTree n (Node _ (x:xs)) = let result = numberForest (n+1) xs
in (Node n (fst result), snd result)
You can further improve on this using pattern matching inside the let:
numberTree n (Node _ (x:xs)) = let (forest, n') = numberForest (n+1) xs
in (Node n forest, n')
The state monad is your friend.
import Control.Monad.Trans.State
data Tree a = Node a (Forest a)
type Forest a = [Tree a]
numberTreeS :: Tree a -> State Int (Tree Int)
numberTreeS (Node _ xs) = do
n <- get
put (n + 1)
xs' <- numberForestS xs
return $ Node n xs'
numberForestS :: Forest a -> State Int (Forest Int)
numberForestS = mapM numberTreeS
numberForest :: Forest a -> Forest Int
numberForest xs = evalState (numberForestS xs) 0
This is more readable, than explicit state passing.

How to optimize a transitive closure?

I have the following code, which I would like to optimize.
I'm particularly unhappy with nub :
deep (Op o x) = [f (Op o x)] ++ map (\y->(Op o y)) (sf x)
deep x = [x]
sf [x] = [[f x]]
sf (x:xs) = map (\y->(y:xs)) (deep x) ++ map (x:) (sf xs)
eqlst l
| l == ll = l
| otherwise = eqlst ll
where ll = nub $ l ++ (concat $ map deep l)
For a full understanding of this, I provide all my code, which is not so long:
module Nat ( Nat, Operator(Add, Mul), Exp(Const, Name, Op), toNat, fromNat) where
import Data.List(nub)
newtype Nat = Nat Integer deriving (Eq, Show, Ord)
toNat :: Integer -> Nat
toNat x | x <= 0 = error "Natural numbers should be positive."
| otherwise = Nat x
fromNat :: Nat -> Integer
fromNat (Nat n) = n
instance Num Nat where
fromInteger = toNat
x + y = toNat (fromNat x + fromNat y)
x - y = toNat (fromNat x - fromNat y)
x * y = toNat (fromNat x * fromNat y)
abs x = x
signum x = 1
data Operator = Add | Sub | Mul
deriving (Eq, Show, Ord)
data Exp = Const Nat | Name { name::String } | Op{ op::Operator, kids::[Exp] }
deriving (Eq, Ord)
precedence :: Exp -> Integer
precedence (Const x) = 10
precedence (Name x) = 10
precedence (Op Add x) = 6
precedence (Op Sub x) = 6
precedence (Op Mul x) = 7
instance Show Exp where
show Op { op = Add, kids = [x, y] } =
let left = if precedence x <= 6 then "(" ++ show x ++ ")" else show x in
let right = if precedence y <= 6 then "(" ++ show y ++ ")" else show y in
left ++ "+" ++ right
show Op { op = Sub, kids = [x, y] } =
let left = if precedence x <= 6 then "(" ++ show x ++ ")" else show x in
let right = if precedence y <= 6 then "(" ++ show y ++ ")" else show y in
left ++ "-" ++ right
show Op { op = Mul, kids = [x, y] } =
let left = if precedence x <= 7 then "(" ++ show x ++ ")" else show x in
let right = if precedence y <= 7 then "(" ++ show y ++ ")" else show y in
left ++ "∙" ++ right
show (Const (Nat x)) = show x
show (Name x) = x
show x = "wat"
instance Num Exp where
fromInteger = Const . toNat
(Const x) + (Const y) = Const (x+y)
x + y = simplify $ Op { op = Add, kids = [x, y] }
(Const x) - (Const y) = Const (x-y)
x - y = simplify $ Op { op = Sub, kids = [x, y] }
(Const x) * (Const y) = Const (x*y)
x * y = simplify $ Op { op = Mul, kids = [x, y] }
abs x = x
signum x = 1
simplify :: Exp -> Exp
simplify (Op Mul [x,1]) = x
simplify (Op Mul [1,x]) = x
simplify (Op Sub [x,y])
| x == y = 0
| otherwise = (Op Sub [x,y])
simplify x = x
f (Op Add [x,y]) = y+x
f (Op Sub [x,y]) = y-x
f (Op Mul [x,y]) = y*x
f x = x
deep (Op o x) = [f (Op o x)] ++ map (\y->(Op o y)) (sf x)
deep x = [x]
sf [x] = [[f x]]
sf (x:xs) = map (\y->(y:xs)) (deep x) ++ map (x:) (sf xs)
eqlst l
| l == ll = l
| otherwise = eqlst ll
where ll = nub $ l ++ (concat $ map deep l)
eq x = eqlst [x]
main = do
let x = Name "x";y = Name "x";z = Name "z";w = Name "w";q = Name "q"
let g = (x+y+(z+w)+q)+(x+y+(z+w)+q)+(x+y+(z+w)+q)+(x+y+(z+w)+q)
putStr $ unlines $ map show $ eq g
I also have a side question, about the function deep and sf that are using f::Exp->Exp. In the end, f should probably be f::[Exp]->[Exp].
Right now, f only performs one kind of transformation. In the end, I would like it to perform many kinds of transformations, for example :
a+b->b+a, (a+b)+c->a+(b+c), etc.
The function nub is inefficient since it only uses an Eq constraint and therefore has to compare every nondiscarded pair of elements. Using the more efficient Data.Set, which is based internally on sorted trees, should improve on this:
import qualified Data.Set as S
eqset s
| s == ss = s
| otherwise = eqset ss
where ss = S.unions $ s : map (S.fromList . deep) (S.toList s)
eqlst = S.toList . eqset . S.fromList

Resources