haskell show with function application - haskell

this line of code in Haskell produces an error on compilation:
lineStat :: String -> [String]
lineStat xs = zipWith (\n line -> show n ++ " " ++ show $ length line) [1..] $ lines xs
Error:
Couldn't match expected type Int -> String with actual type [Char]
The first argument of ($) takes one argument,but its type [Char] has none
However this line of code works:
lineStat xs = zipWith (\n line -> show n ++ " " ++ show (length line)) [1..] $ lines xs
Why?

It's a precedence issue.
show n ++ " " ++ show $ length line
means
(show n ++ " " ++ show) (length line)
which makes no sense since show is not a string. It does not mean
show n ++ " " ++ (show (length line))
To get the wanted one, you need parentheses. Use one of these:
zipWith (\n line -> show n ++ " " ++ show (length line)) [1..] $ lines xs
-- or
zipWith (\n line -> show n ++ " " ++ (show $ length line)) [1..] $ lines xs
I'd prefer the former since it's simpler.

Your problem boils down to:
*Main> let line = "abc"
*Main> " " ++ show (length line)
" 3"
*Main> " " ++ show $length line
<interactive>:9:1: error:
• Couldn't match expected type ‘Int -> t’ with actual type ‘[Char]’
The root cause for this is that $ has lower precedence than ++:
*Main> :info (++)
...
infixr 5 ++
*Main> :info ($)
...
infixr 0 $
as defined in the Haskell Report
Therefore, you need parentheses around show $ length line.

Related

* Couldn't match type `(Float, Float)' with `[Point]'

CODE
type Point = (Float,Float)
type Candidate = (Point,Point,[Point],Float)
print_list :: [[Point]] -> String
print_list [] = ""
print_list [x:xs] = show x ++ "," ++ print_list(xs)
candidate_to_string :: Candidate -> String
candidate_to_string (a, x, y:ys, z) = "Start point: " ++ show a ++
"\nSupporting Points: " ++ print_list(y:ys) ++ "\nEnd Point: " ++ show x
++ "\nTime: " ++ show z
ERROR MESSAGE
C:\\Users\conor\Desktop\haskellcoursework.hs:47:50: error:
* Couldn't match type `(Float, Float)' with `[Point]'
Expected type: [[Point]]
Actual type: [Point]
* In the first argument of `print_list', namely `(xs)'
In the second argument of `(++)', namely `print_list (xs)'
In the second argument of `(++)', namely `"," ++ print_list (xs)'
|
47 | print_list [x:xs] = show x ++ "," ++ print_list(xs)
| ^^
C:\\Users\conor\Desktop\haskellcoursework.hs:50:107: error:
* Couldn't match type `(Float, Float)' with `[Point]'
Expected type: [[Point]]
Actual type: [Point]
* In the first argument of `print_list', namely `(y : ys)'
In the first argument of `(++)', namely `print_list (y : ys)'
In the second argument of `(++)', namely
`print_list (y : ys)
++ "\nEnd Point: " ++ show x ++ "\nTime: " ++ show z'
|
50 | candidate_to_string (a, x, y:ys, z) = "Start point: " ++ show a ++
"\nSupporting Points: " ++ print_list(y:ys) ++ "\nEnd Point: " ++ show x ++
"\nTime: " ++ show z ^^^^
|
The signatures I have used are specified for me. My task is to write a function candidate_to_string :: Candidate -> String which creates a string representation
of a candidate. Each Point is written in its own line starting with the start point, followed by
all supporting points and ending with the end point. The time is printed in an extra line consisting
of the string “Time: ” and the value.
print_list requires a [[Point]] -- a list of lists of points
print_list :: [[Point]] -> String
-- ^^^^^^^^^ --
but here you pass it a [Point] a list of points. Hence, a type error arises:
candidate_to_string :: Candidate -> String
candidate_to_string (a, x, y:ys, z) =
... print_list(y:ys) ...
-- ^^^^^^ this is a [Point]
The mistake is that print_list should instead be [Point] -> String. More in detail,
print_list [x:xs] = show x ++ "," ++ print_list(xs)
is wrong, since [x:xs] is a list containing only one element, namely the list x:xs. You don't want a list-of-lists here, so simply use something like
print_list :: [Point] -> String
print_list [] = ""
print_list [x] = show x -- we don't want a trailing comma here
print_list (x:xs) = show x ++ "," ++ print_list xs

Haskell in append few list together

I want to the value of one element in a List , So I did the
changePoint :: (Int,Int) -> [[[Char]]] -> [[Char]]
changePoint (x,y) maze = let
linelement = maze !! (y-1)
-- value ["X"," "," ",...," ","X"]
rowelement = chunksOf 1 $ head linelement
-- type:[[a]]; value ["X"," "," "," "," "," "," "," "," "," "," "," "," ","X"]
l = length rowelement
list = take (x-1) rowelement
-- in take (x-1) rowelement -- ["X"]
in take (x-1) rowelement ++ (["."] : (drop (x) rowelement))
I want to append the list "take (x-1) rowelement" and "["."]" and "drop (x) rowelement", the type of list will be [[a]]
Couldn't match expected type ‘Char’ with actual type ‘[Char]’
In the expression: "."
In the first argument of ‘(:)’, namely ‘["."]’
In the second argument of ‘(++)’, namely
‘(["."] : (drop (x) rowelement))’ Failed, modules loaded: none.
x = 2 .
I know the problem is "["."]",but I really don't how to fix it .
The true return should be ["X","."," "," ",..,"X" ]
In GHCI, you can use :t somefunction to get the type of somefunction.
Here, the problem is with (:), lets see what GHCI tells us.
Prelude λ> :t (:)
(:) :: a -> [a] -> [a]
So (:) takes an a, a list of as and returns a new list. Specialized for the use case at hand, (:) has type [Char] -> [[Char]] -> [[Char]] (because a = [Char]). But ["."] has type [[Char]], so it does not match what's expected for (:).
Now, if you use take (x-1) rowelement ++ ("." : (drop (x) rowelement)) (note the missing [] around "."), the function should compile fine.
Either use:
(take (x-1) rowelement) ++ ["."] ++ (drop x rowelement)
Or
(take (x-1) rowelement) ++ ("." : (drop x rowelement))
The [ and ] are not necessary

How to print list of tuples like table in Haskell

i have a list of tuples like:
[("3",69.46),("4",38.32),("5",111.67),("9",97.13)]
and i want to print this list of tuple like :
3 69.46
4 38.32
5 111.67
9 97.13
What is the best way to implement this?
(The length of list is dynamic)
Thanks
One way would be like this:
printList xs = mapM_ (\(a,b) -> putStr a >> putStr (" " ++ show b) >> putStrLn "") xs
Or in a more readable way:
printList xs = mapM_ (\(a,b) -> do
putStr a
putStr (" " ++ show b)
putStrLn "") xs
Or as #icktoofay points out you can use a single putStrLn:
printList xs = mapM_ (\(a,b) -> putStrLn $ a ++ " " ++ show b) xs
In ghci:
λ> printList [("3",69.46),("4",38.32),("5",111.67),("9",97.13)]
3 69.46
4 38.32
5 111.67
9 97.13

Couldn't match expected type

I have the following Haskell program:
catlines = unlines . zipWith (\(n,l) -> show n ++ l) [0..]
main = putStrLn $ catlines ["A", "B"]
When I try to compile it, GHC gives the following error:
catlines.hs:1:41:
Couldn't match expected type `b0 -> String' with actual type `[a0]'
In the expression: show n ++ l
In the first argument of `zipWith', namely
`(\ (n, l) -> show n ++ l)'
In the second argument of `(.)', namely
`zipWith (\ (n, l) -> show n ++ l) [0 .. ]'
From what I know, this should compile. I have no idea what's wrong.
The problem is that the function passed to zipWith should take two arguments, not a tuple. Try it like this:
zipWith (\n l -> show n ++ l)

++ operator with String and IO String

explandDol :: String -> String -> [String] -> IO String
explandDol conclusion operators atoms =
let (ys,zs) = splitAt (head (take 1 replacement)) conclusion in ys ++ getConclusion operators atoms ++ (tail zs)
where replacement = elemIndices '$' conclusion
getConclusion :: String -> [String] -> IO String
getConclusion operators atoms =
runRVar (choice [atom1 ++ " " ++ [operator] ++ " " ++ atom2 | atom1 <- atoms, atom2 <- atoms, operator <- operators,checkAtoms atom1 atom2]) StdRandom
Is there a good way to fix this? I am getting this error:
/home/joe/Documents/haskell/LAG/main/main.hs: line 73, column 69:
Couldn't match expected type `IO String' with actual type `[Char]'
In the expression: ys ++ getConclusion operators atoms ++ (tail zs)
In the expression:
let (ys, zs) = splitAt (head (take 1 replacement)) conclusion
in ys ++ getConclusion operators atoms ++ (tail zs)
In an equation for `explandDol':
explandDol conclusion operators atoms
= let (ys, zs) = splitAt (head (take 1 replacement)) conclusion
in ys ++ getConclusion operators atoms ++ (tail zs)
where
replacement = elemIndices '$' conclusion
/home/joe/Documents/haskell/LAG/main/main.hs: line 73, column 75:
Couldn't match expected type `[Char]' with actual type `IO String'
In the return type of a call of `getConclusion'
In the first argument of `(++)', namely
`getConclusion operators atoms'
In the second argument of `(++)', namely
`getConclusion operators atoms ++ (tail zs)'
/home/joe/Documents/haskell/LAG/main/main.hs: line 73, column 75:
Warning: Redundant bracket
Found:
getConclusion operators atoms ++ (tail zs)
Why not:
getConclusion operators atoms ++ tail zs
Because value returned by getConclusion is IO String you cannot simply use it with functions operating on unwrapped values. Either first unwrap value using x <- getConclusion operators atom or if you want function composition use fmap.

Resources