I'm trying to add certain letters of a String
in a String
list.
For example: "Haskell" -> ['a', 's']
(only a
and s
)
After run I get the error message "Note in scope: xs
". So it lacks a list(I think). I have no problems to convert a list to a new list (eg mirrorList), but how can I "create" a list after I get a String Input?
letterList :: String -> [String]
letterList s = let x = head s in
if x == 'a' || x == 's' then x:xs
else letterList (tail x)
Before getting to your precise question, let's fix the types. Your example "Haskell" -> ['a', 's']
indicates that the type of this function is String -> String
, not String -> [String]
. Note that String
is just a type alias for [Char]
.
The error message means you have an expression that refers to a value xs
, but nowhere have you defined anything named xs
. I suspect you were going for with x:xs
is pattern matching. The pattern goes to the left of the =
, and that declares x
and xs
which you can refer to on the right side. And since the empty list can't be destructured into a head and tail, you need a separate case for it.
I'm guessing the result you're after looks something like this:
letterList :: String -> String
letterList [] = []
letterList (x:xs) = if x == 'a' || x == 's' then x:rest else rest
where rest = letterList xs
I assume your use of recursion here is just for practice, but for what it's worth, I would recommend writing this as
letterList :: String -> String
letterList = filter (`elem` "as")
Not in scope:
xs
That just means what it says: there is no variable called xs
to be found, yet you attempt to use it. It's much the same error you'd also get in Java when trying to, say, call a method that's nowhere defined.
I have no problems to convert a list to a new list (eg mirrorList)
That's something you never † need in Haskell. When you have a list you can always use it directly and in whichever way you fancy. Because of referential transparency, there can never be a difference between a value and a copy of it. And I'm not sure what you mean by “converting” here, but generally it is avoided to convert anything in Haskell: parametric polymorphism usually allows you to generate the right type right from the beginning.
Now as to “how do I create a list” – you already do it! The cons (prepend) operator :
in x:xs
constructs a new list. ...Granted, it's based on the already existing list xs
. This is in fact the only way to generate a new list, because the list constructor always needs a tail to prepend elements before. If you don't want/need/have any such list, use the empty one , []
, that's always available.
† Even in Haskell, you sometimes need to work with mutable data (usually arrays in the ST
monad – mutable internally but still guaranteed referentially transpart when viewed from the outside). Within such a computation, it may be necessary to copy an array, just like it can be in procedural languages.
The error message says - you are using xs
on the right hand side but do not define it before its usage (ie no let
statement before, no where
statement after, and not on the left hand side either.
You have another problem is that you are basically implementing a filter, but the result type is a String
not a [String]
!
letterList :: String -> [String]
letterList [] = []
letterList (x:xs) = if x == 'a' || x == 's'
then [x]: letterList xs
else letterList xs
String
! String
in head = x
and tail = xs
, which is more readable and correct ( tail x
is wrong you try to take the end of a single letter!) [x]
transforms a single letter Char
in a String = [Char]
. letterList str = [[x] | x <- str, x `elem` "as"]
this is called list comprehension, which would be the next "homework" I will give you to think about.
or
letterList str = map (\x -> [x]) $ filter (`elem` "as") str
Which uses higher order functions ( filter
and map
) which is the second task I'll give you.
Of course you can also change the type signature to String -> String
as @ChrisMartin shows - then you can omit the [
, ]
in the [x]
statements, and respectively omit the map (\\x -> [x])
thing.
似乎是复制粘贴错误:尝试将xs替换为(tail x)...,然后考虑emoty-list问题……也许您也将替换左侧的;-)
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.