I am new to Haskell and functional programming, and can't understand why this function cannot identify the correct type:
mformat :: [Char] -> [Char] -> [Char]
mformat first last = ((formatted first last) ++ " " ++ first ++ " " ++ last ++ ".")
where formatted (f:_) (l:_) = (f ++ "." ++ l ++ ".")
which causes the error:
teststuff.hs:42:40: error:
* Couldn't match type `Char' with `[Char]'
Expected: [[Char]]
Actual: [Char]
* In the second argument of `formatted', namely `last'
In the first argument of `(++)', namely `(formatted first last)'
In the expression:
(formatted first last) ++ " " ++ first ++ " " ++ last ++ "."
|
42 | mformat first last = ((formatted first last) ++ " " ++ first ++ " " ++ last ++ ".")
| ^^^^
Failed, no modules loaded.
I don't understand what is wrong here, any help would be appreciated.
The issue is in your formatted function. You are pattern matching on a String, you get Chars (f & l) and then you try concatenating them with a String. You cannot concatenate a Char with a String ([Char]).
mformat :: String -> String -> String
mformat first last = ((formatted first last) ++ " " ++ first ++ " " ++ last ++ ".")
where
formatted :: String -> String -> String
formatted (f:_) (l:_) = ([f] ++ "." ++ [l] ++ ".")
or
-- ...
formatted (f:_) (l:_) = (f : "." ++ l : ".")
The type checker thinks thinks that f and l in your case must be lists - because you are attempting to concatenate them. Then it infers (via pattern matching) from the list constructor, that first and last are lists of Strings i.e. [String] or [[Char]].
Related
I have been trying to to iterate the cand data in order to apply a function "pt_string".
Pt :: (Float, Float)
Person :: (Pt, Pt, [Pt], Float)
My idea is to call that function "pt_string" in a different way for each element of the tupple.
For example:
pt_string Point (first)
map pt_string [Point]
pt_string Point (second)
show "Tmp"
So far, I got:
pt_string :: pt -> String
pt_string pt = "(" ++ show (fst pt) ++ "," ++ show (snd pt) ++ ")\n"
Which works fine. But how can I create cand_to_string :: cand -> String in the above order?
Thanks!
Assuming
type Candidate = (Point, Point, [Point], Float)
you can use
candidate_to_string :: Candidate -> String
candidate_to_string (p1, p2, ps, f) =
"(" ++
point_to_string p1 ++ ", " ++
point_to_string p2 ++ ", " ++
points_to_string ps ++ ", " ++
show f ++
")"
which relies on
points_to_string :: [Point] -> String
points_to_string ps = "[" ++ intercalate ", " (map point_to_string ps) ++ "]"
exploiting Data.List.intercalate to add commas between the points.
Also note that, if you simply want the standard list/tuple printing format, you can directly use
candidate_to_string :: Candidate -> String
candidate_to_string = show
I'm trying to do the following
S = lists:concat(A) ++ " " ++ [254,874] ++ "\n".
it gives me error message
** exception error: no match of right hand side value [51,50,52,51,53,54,53,54,55,54,54,53,52,51,32,254,874,10]
but it works fine for string values "[254,874]"
how can I make [254,874] to "[254,874]"
You maybe forgot f(S) for previous calculation. Try it before using your command:
1> f(S).
ok
2> S = lists:concat(A) ++ " " ++ [254,874] ++ "\n".
Moreover, you can use $[ or $] for indicate "[" "]" in ASCII
3> $[.
91
4> $].
93
5> S = lists:concat(A) ++ " " ++ [91,254,874,93] ++ "\n".
found the answer
A = [254,876].
lists:flatten(io_lib:format("~p",[A])).
this gives exact result
"[254,876]"
To convert list of integers to string
for your case I would have done:
[A, B] = [254,876],
C = "[" ++ integer_to_list(A) ++ "," ++ integer_to_list(B) ++ "]".
for a more generic case:
-module(l2s).
-compile(export_all).
list_to_string([H|List]) ->
list_to_string(List, "[" ++ integer_to_list(H)).
list_to_string([], String) -> String ++ "]";
list_to_string([H | List], String) ->
list_to_string(List, String ++ "," ++ integer_to_list(H)).
Test:
Eshell V7.3 (abort with ^G)
1> A = [1,2,3,4,5].
[1,2,3,4,5]
2> l2s:list_to_string(A).
"[1,2,3,4,5]"
"["++lists:concat(lists:join(",",A))++"]".
"[1,2,3,4]"
I am trying to write a recursive data structure in Haskell in order to represent an expression tree. I have this data type:
data Expr =
And(Expr, Expr ) |
Or (Expr, Expr ) |
(/) Expr Expr
And I would like to pattern-match every data constructor in a function:
toStringE :: Expr -> String
toStringE e = case e of
And(a,b) -> "and(" ++ toStringE a ++ ", " ++ toStringE b ++ ")"
Or(a,b) -> "or(" ++ toStringE a ++ ", " ++ toStringE b ++ ")"
(/) expr1 expr2 -> (toStringE expr1) ++ " / " ++ (toStringE expr2)
But when I try to compile, I get this error on the last line of the toStringE function:
Parse error in pattern: (/)
What do you think I am doing wrong?
(/) isn't a valid infix data constructor. All valid infix data constructors start with :. You could name the constructor (:/), for instance.
The reason for this is that pattern matching depends on the ability to determine whether something is a constructor or not lexically. It does that by examining the first character of the identifier. If it's a capital letter or :, it is a constructor. If it's not one of those, it's a variable to be bound by the pattern match.
Hey so im trying to pick a random element from this list of list Strings however when i try to add choice to the list comprehension ...
{-# LANGUAGE UnicodeSyntax #-}
import System.Random(randomRIO)
import Data.Random.Extras(choice)
import Data.Char (digitToInt)
...
getConclusion :: String -> String -> [String]
getConclusion operators atoms =
choice [[atom1] ++ " " ++ [operator] ++ " " ++ [atom2] | atom1 <- atoms, atom2 <- atoms, operator <- operators]
... I get this error:
/home/joe/Documents/haskell/LAG/main/main.hs: line 56, column 4:
Couldn't match type `Data.RVar.RVarT
Data.Functor.Identity.Identity [Char]'
with `[String]'
Expected type: [String]
Actual type: Data.RVar.RVar [Char]
In the return type of a call of `choice'
In the expression:
choice
[[atom1] ++ " " ++ [operator] ++ " " ++ [atom2] |
atom1 <- atoms, atom2 <- atoms, operator <- operators]
In an equation for `getConclusion':
getConclusion operators atoms
= choice
[[atom1] ++ " " ++ [operator] ++ " " ++ [atom2] |
atom1 <- atoms, atom2 <- atoms, operator <- operators]
Take a look at the type of choice :: [a] -> RVar a. Your function should have the type String -> String -> RVar String. The RVarT Data.Functor.Identity.Identity [Char] is just a long synonym for RVar String.
How can I create a newline inside a String? Is it possible without using IO ()?
formatRow :: Car -> String
formatRow (a, d:ds, c, x:xs) = a ++ " | " ++ x ++ concat xs ++ " | " ++ show c ++ " | " ++ d ++ concat ds ++ (show '\n')
To create a string containing a newline, just write "\n".
If you run your program on Windows, it will automatically be converted to "\r\n".
Note that calling show on it will escape the newline (or any other meta-characters), so don't do foo ++ (show "\n") or foo ++ (show '\n') - just use foo ++ "\n".
Also note that if you just evaluate a string expression in GHCi without using putStr or putStrLn, it will just call show on it, so for example the string "foo\n" will display as "foo\n" in GHCi, but that does not change the fact that it's a string containing a newline and it will print that way, once you output it using putStr.