Haskell [x] and x notation - as-pattern example
I am reading Learn you a Haskell for great good and on page 40 - as-patterns. I have changed the example slightly to be: firstLetter :: String -> String firstLetter "" = "Empty string, oops" firstLetter all@(x:xs) = "The first letter of " ++ all ++ " is " ++ [x] ++ " otherbit " ++ xs Then can use like this: *Main> firstLetter "Qwerty" "The first letter of Qwerty is Q otherbit werty" But I was confused about the difference between [x] and x and why I have to use [x] in the above example. For example if I change to firstLetter :: String -> String firstLetter "" = "Empty string, oops" firstLetter all@(x:xs) = "The first letter of " ++ all ++ " is " ++ x ++ " otherbit " ++ xs I get error: Couldn't match expected type `[Char]' with actual type `Char' In the first argument of `(++)', namely `x' In the second argument of `(++)', namely `x ++ " otherbit " ++ xs' In the second argument of `(++)', namely `" is " ++ x ++ " otherbit " ++ xs' I can use xs to print "werty" but have to use [x] to print "Q". Why is that? What does [x] mean? In the (x:xs) : just delimits each element. so x is the first element. Why can I not print by using x? Also xs is of what type? list of values? So does this mean x is an element and xs must be of type list? Confused...
Hi, Write firstLetter all@(x:xs) = "The first letter of " ++ all ++ " is " ++ [x] ++ " otherbit " ++ xs Nadav From: haskell-bounces@haskell.org [mailto:haskell-bounces@haskell.org] On Behalf Of Angus Comber Sent: Wednesday, April 03, 2013 12:01 PM To: Haskell Mailing List Subject: [Haskell] Haskell [x] and x notation - as-pattern example I am reading Learn you a Haskell for great good and on page 40 - as-patterns. I have changed the example slightly to be: firstLetter :: String -> String firstLetter "" = "Empty string, oops" firstLetter all@(x:xs) = "The first letter of " ++ all ++ " is " ++ [x] ++ " otherbit " ++ xs Then can use like this: *Main> firstLetter "Qwerty" "The first letter of Qwerty is Q otherbit werty" But I was confused about the difference between [x] and x and why I have to use [x] in the above example. For example if I change to firstLetter :: String -> String firstLetter "" = "Empty string, oops" firstLetter all@(x:xs) = "The first letter of " ++ all ++ " is " ++ x ++ " otherbit " ++ xs I get error: Couldn't match expected type `[Char]' with actual type `Char' In the first argument of `(++)', namely `x' In the second argument of `(++)', namely `x ++ " otherbit " ++ xs' In the second argument of `(++)', namely `" is " ++ x ++ " otherbit " ++ xs' I can use xs to print "werty" but have to use [x] to print "Q". Why is that? What does [x] mean? In the (x:xs) : just delimits each element. so x is the first element. Why can I not print by using x? Also xs is of what type? list of values? So does this mean x is an element and xs must be of type list? Confused...
On Wed, 3 Apr 2013, Angus Comber wrote:
I am reading Learn you a Haskell for great good and on page 40 - as-patterns.
This question is certainly better for the beginners list: http://www.haskell.org/mailman/listinfo/beginners In your case x :: Char xs :: [Char] [x] :: Char That is, the brackets create a list from the single character x. This way it provides the list type as required by (++).
Also xs is of what type? list of values? So does this mean x is an element and xs must be of type list
Exactly. x is of type Char and xs is of type [Char]. The list concatenation function (++) expects both of its arguments to be lists, so that's the reason you need to turn a Char x into a list containing only one value ([x]). — Sincerely yours, Daniil Frumin Angus Comber <anguscomber@gmail.com="mailto:anguscomber@gmail.com">> wrote: I am reading Learn you a Haskell for great good and on page 40 - as-patterns. I have changed the example slightly to be: firstLetter :: String -> String firstLetter "" = "Empty string, oops" firstLetter all@(x:xs) = "The first letter of " ++ all ++ " is " ++ [x] ++ " otherbit " ++ xs Then can use like this: *Main> firstLetter "Qwerty" "The first letter of Qwerty is Q otherbit werty" But I was confused about the difference between [x] and x and why I have to use [x] in the above example. For example if I change to firstLetter :: String -> String firstLetter "" = "Empty string, oops" firstLetter all@(x:xs) = "The first letter of " ++ all ++ " is " ++ x ++ " otherbit " ++ xs I get error: Couldn't match expected type `[Char]' with actual type `Char' In the first argument of `(++)', namely `x' In the second argument of `(++)', namely `x ++ " otherbit " ++ xs' In the second argument of `(++)', namely `" is " ++ x ++ " otherbit " ++ xs' I can use xs to print "werty" but have to use [x] to print "Q". Why is that? What does [x] mean? In the (x:xs) : just delimits each element. so x is the first element. Why can I not print by using x? Also xs is of what type? list of values? So does this mean x is an element and xs must be of type list? Confused...
On Wed, Apr 3, 2013 at 5:01 AM, Angus Comber <anguscomber@gmail.com> wrote:
In the (x:xs) : just delimits each element. so x is the first element. Why can I not print by using x?
Also xs is of what type? list of values? So does this mean x is an element and xs must be of type list? Confused...
Actually, you just answered yourself. x is an element, xs is a list. (++) combines lists, so to insert your element using (++) you need to make it a list. [x] is a list containing your element x and nothing else. Another way to do it is to do the same as the pattern match, but in this case that's kinda ugly: firstLetter all@(x:xs) = "The first letter of " ++ all ++ " is " ++ (x : " otherbit ") ++ xs or firstLetter all@(x:xs) = "The first letter of " ++ all ++ " is " ++ (x : []) ++ " otherbit " ++ xs (note that "is of type list" is incomplete; list of *what*? In this case, list of Char. Haskell String is just [Char] (list of Char), which is highly convenient but a bit slow in real programs that manipulate a lot of String-s.) -- brandon s allbery kf8nh sine nomine associates allbery.b@gmail.com ballbery@sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net
Yes it seems that ++ concatenates lists not elements and that was the underlying problem. I have subscribed to the beginners list - didn't know there was one for people like me just starting to walk :) On 3 April 2013 14:39, Brandon Allbery <allbery.b@gmail.com> wrote:
On Wed, Apr 3, 2013 at 5:01 AM, Angus Comber <anguscomber@gmail.com>wrote:
In the (x:xs) : just delimits each element. so x is the first element. Why can I not print by using x?
Also xs is of what type? list of values? So does this mean x is an element and xs must be of type list? Confused...
Actually, you just answered yourself. x is an element, xs is a list. (++) combines lists, so to insert your element using (++) you need to make it a list. [x] is a list containing your element x and nothing else.
Another way to do it is to do the same as the pattern match, but in this case that's kinda ugly:
firstLetter all@(x:xs) = "The first letter of " ++ all ++ " is " ++ (x : " otherbit ") ++ xs
or
firstLetter all@(x:xs) = "The first letter of " ++ all ++ " is " ++ (x : []) ++ " otherbit " ++ xs
(note that "is of type list" is incomplete; list of *what*? In this case, list of Char. Haskell String is just [Char] (list of Char), which is highly convenient but a bit slow in real programs that manipulate a lot of String-s.)
-- brandon s allbery kf8nh sine nomine associates allbery.b@gmail.com ballbery@sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net
Hi Angus, Angus Comber wrote:
Also xs is of what type? list of values? So does this mean x is an element and xs must be of type list? Confused...
Here is how you can use ghci to investigate such questions:
ghci GHCi, version 7.4.2: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done.
Prelude> let all@(x:xs) = "hello world"
Prelude> x 'h'
Prelude> xs "ello world"
Prelude> all "hello world"
Prelude> :t x x :: Char
Prelude> :t xs xs :: [Char]
Prelude> :t all all :: [Char]
Prelude> x 'h'
Prelude> [x] "h"
Prelude> :t x x :: Char
Prelude> :t [x] [x] :: [Char]
Prelude> :q Leaving GHCi.
Tillmann PS. The haskell@haskell.org list is mostly for announcements, so questions like this are better suited for beginners@haskell.org or haskell-cafe@haskell.org.
participants (7)
-
Angus Comber -
Brandon Allbery -
Chernin, Nadav -
Daniel Frumin -
Denis Kasak -
Henning Thielemann -
Tillmann Rendel