left :: [String]->[Char]->Char
left [] _ = []
left (x:xs) (head xs) = x -- it says error at head
I used proper parenthesis but still taking parse error.By the way, I m trying to get previous element in list such as [["A"],["B"],["C"],["D"],["E"]]
. Maybe I have some other mistakes. Pls correct me .
2nd question is how can pick previous elements previous indexed character. Such as giving function this list [["J","O","H","N"],["A","L","I","C","E"]] and "C" , I want to expect to get "H". I mean "C" is 2nd element 4th index and "H" is previous elements 3rd index. Thnx in advance
If I understood you well, you need a function which find a character in a list of String
, and return the character of the preceding string at the preceding index.
Something like:
f ["JOHN", "ALICE"] 'C' == 'H'
First you need to know that Char
literals are delimited with simple quotes in Haskell ('A'
), and String
literals with double quotes ("ABC"
).
Since in Haskell String
is an alias for [Char]
, "ABC"
is equivalent to ['A', 'B', 'C']
.
This said, in Haskell you can't define a function like this: f a a = stuff
. GHC will complain that a
is defined multiple times.
So to check if two arguments have some property, you need guard patterns.
So I would write your first function like this:
left :: [String] -> String -> String
left [] _ = ""
left [x] _ = ""
left (x1:x2:xs) str
| x2 == str = x1
| otherwise = left (x2:xs) str
For your second question:
import Data.List
f :: [String] -> Char -> Maybe Char
f [] _ = Nothing
f [a] _ = Nothing
f (x1:x2:xs) c
| Just i <- elemIndex c x2 = Just $ x1 !! (i-1)
| otherwise = f (x2:xs) c
Notes:
left
should also return a Maybe String
in case str
isn't found or is first.f
doesn't check if x1
is actually long enoughEDIT:
A somewhat more clever approach with zip
(in module Data.List
).
f :: [String] -> Char -> Maybe Char
f [] _ = Nothing
f [_] _ = Nothing
f (x1:"":xs) c = f xs c
f (x1:x2:xs) c = f' (zip x1 (tail x2))
where f' [] = f (x2:xs) c
f' ((a,b):l) = if b == c then a else f' l
This version won't crash. It will return the first character which satisfies "being mth character in nth string, while the (m+1)th character in (n+1)th string" is c
. The result will be wrapped in a Maybe
(Just 'H'
). Otherwise, it returns Nothing
(Maybe
is roughly the nullable type for Haskell).
zip
is a function which merges two lists in one list of pairs:
zip ['a', 'b', 'c'] [1, 2] == [('a', 1), ('b', 2)]
The size of the resulting list is the one of the smallest. So in the example, what happens is:
zip "JOHN" (tail "ALICE") == [('J','L'), ('O', 'I'), ('H', 'C'), ('N', 'E')]
You then just have to check is the second character is the searched one, and then return the first character of the pair.