Home > Blockchain >  Modifying a list using recursion
Modifying a list using recursion

Time:11-21

I have a list with elements of type LocalType (defined below), I wish to modify this list in function of which subtptype the element is belonging too. An element of type End stays in the list of type End. For an element of type Prl (End Bar End), the first End shall stay in the list, the second End shall be appended to the list. E.g [End, (Prl s Bar ss)] -> [End, s, ss] E.g [End, End Bar End] -> [End, End, End] This is how I thought of implementing it,

sepTimes :: [LocalType] -> [LocalType]
sepTimes(x:[]) = [x]
sepTimes(x:xs)
    | x == End = sepTimes (x:xs)
    | x == (Prl s Bar ss) = do 
        sepTimes (s:xs)
        sepTimes (ss:xs)

As the error messages states, I am unable to retrive the elements s and ss corresponding to End and End in the example of Prl (End Bar End).

app\Sequents.hs:44:17: error: Variable not in scope: s :: LocalType
   |
44 |     | x == (Prl s Bar ss) = do
   |                 ^

app\Sequents.hs:44:23: error:
    * Variable not in scope: ss :: LocalType
    * Perhaps you meant `xs' (line 42)
   |
44 |     | x == (Prl s Bar ss) = do
   |                       ^^

app\Sequents.hs:45:19: error: Variable not in scope: s :: LocalType
   |
45 |         sepTimes (s:xs)
   |                   ^

app\Sequents.hs:46:19: error:
    * Variable not in scope: ss :: LocalType
    * Perhaps you meant `xs' (line 42)
   |
46 |         sepTimes (ss:xs)
   |                   ^^

Here are the defined datatypes :

data Seperator = Bar | BackAmpersand
               deriving (Show, Eq, Ord, Read)
data LocalType = End                      
               | Prl LocalType Seperator LocalType
               deriving (Eq, Ord, Read)

CodePudding user response:

You're confusing equality checks with pattern matching. Intuitively, all of the following should be the same:

f :: Either Int Char -> String
f (Left i) = show i
f (Right c) = [c]
f :: Either Int Char -> String
f x = case x of
    Left i -> show i
    Right c -> [c]
f :: Either Int Char -> String
f x
 | x==Left i   = show i    -- what?
 | x==Right c  = [c]

But actually, only the first two are equivalent, the last one doesn't work. Why? You can't match a variable out of an equality statement. That may work in some logical languages where the equality is propositional, but Haskell's == operator is simply boolean: it takes two fully known values and tells you whether or not they're exactly the same. I.e., in order to be able to write x==Left i, the variable i must already be defined.

  • Related