I am learning Haskell and following the guide on http://learnyouahaskell.com/starting-out . I am at the point where it is shown:
ghci> let nouns = ["hobo","frog","pope"]
ghci> let adjectives = ["lazy","grouchy","scheming"]
ghci> [adjective ++ " " ++ noun | adjective <- adjectives, noun <- nouns]
["lazy hobo","lazy frog","lazy pope","grouchy hobo","grouchy frog",
"grouchy pope","scheming hobo","scheming frog","scheming pope"]
What I'd like to achieve, it is something similar, but combining the letters contained in two strings, and since strings are basically lists of char in Haskell, this is what I tried:
[x ++ ' ' ++ y | x <- "ab", y <- "cd"]
But the compiler is complaining:
Prelude> [y ++ ' ' ++ y | x <- "abd", y <- "bcd"]
<interactive>:50:2:
Couldn't match expected type ‘[a]’ with actual type ‘Char’
Relevant bindings include it :: [[a]] (bound at <interactive>:50:1)
In the first argument of ‘(++)’, namely ‘y’
In the expression: y ++ ' ' ++ y
<interactive>:50:7:
Couldn't match expected type ‘[a]’ with actual type ‘Char’
Relevant bindings include it :: [[a]] (bound at <interactive>:50:1)
In the first argument of ‘(++)’, namely ‘' '’
In the second argument of ‘(++)’, namely ‘' ' ++ y’
In the expression: y ++ ' ' ++ y
<interactive>:50:14:
Couldn't match expected type ‘[a]’ with actual type ‘Char’
Relevant bindings include it :: [[a]] (bound at <interactive>:50:1)
In the second argument of ‘(++)’, namely ‘y’
In the second argument of ‘(++)’, namely ‘' ' ++ y’
I did a number of tries, such as wrapping the expression in brackets to get a list, changed the space to be a String rather than a char... How can I get it working?
Thanks
++
works only for lists, but x
and y
are only Char
. After all, they're elements from a String
(= [Char]
), whereas the LYAH example had lists of lists of Char
: [String] = [[Char]]
:
-- [a] -> [a] -> [a]
-- vv vv
[y ++ ' ' ++ y | x <- "abd", y <- "bcd"]
-- ^ ^ ^
-- Char Char
-- vs
-- [String] [String]
-- vvvvvvvvvv vvvvv
[adjective ++ " " ++ noun | adjective <- adjectives, noun <- nouns]
-- ^^^^^^^ ^^^^
-- String String
Instead, use (:)
to cons the characters on each other and onto the empty list:
[x : ' ' : y : [] | x <- "abd", y <- "bcd"]
x ++ ' ' ++ y
The actual problem here is, you are trying to concatenate three characters, with a function defined only for list of items. ++
will actually concatenate two lists, not two individual items and give a list.
So, you can fix your program either by converting all the characters to strings, like this
> [[x] ++ " " ++ [y] | x <- "ab", y <- "cd"] ["ac","ad","bc","bd"]
Note the " "
, not ' '
. Because " "
means a string with just a space character, but ' '
means just the space character.
Or, convert y
to a String, use cons
operator with the ' '
, and concatenate it to x
converted to a string, like this
> [[x] ++ (' ' : [y]) | x <- "ab", y <- "cd"] ["ac","ad","bc","bd"]
Or, even simpler and intutive, as suggested by chi , create a list of characters, like this
> [[x, ' ', y] | x <- "ab", y <- "cd"] ["ac","ad","bc","bd"]
Note: Wrapping a character with []
makes it a list of characters with just one character in it. It basically becomes a String.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.