0
votes

What I want to do is to apply the stoline function on each element (String) of the list passed to stomap..

Type of stoline : stoline :: String -> [Obj].

Here is my code :

stomap :: [[String]] -> [Obj]
stomap [[val]] = stoline val
stomap (val:vals) = map (\a -> stoline a) val ++ ...

Example of the data passed to stomap : [["0","133","2"],["6","0","0"],["656","0","3"]].


Error : Couldn't match expected type Obj with actual type [Obj] in the return type of a call of stoline.
The problem is the map function which returns a list (and shouldn't!), but I don't really know how to avoid that problem..

1
FYI, [Obj] is a list, not an array. The semantics and access times are different. For example, lists have O(k) access to the k'th element and arrays have O(1) access to the k'th element. - rampion
Thanks for the comment, I fixed it (writing mistake..) ; +1 ! - Val
Well, according to you, stoline takes a string, not a list of strings. - Luka Horvat
@LukaHorvat : Yes ! But the stomap function is sending a String to stoline... val is [String] and map takes each element (so Strings) of val. - Val

1 Answers

3
votes

Your first case is unnecessary, and there's an error is in your second case:

map (\a -> stoline a) val ++ ...

val here is [String], so map (\a -> stoline a) val is [[Obj]]. Since you're using ++ to combine it with the rest of the results, your ultimate result will be of type [[Obj]], not [Obj].

Let's rework it:

stomap :: [[String]] -> [Obj]
stomap lolos = concatMap (\los -> concatMap (\s -> stoline s) los) lolos

lolos is a list of lists of strings, los is a list of strings, and s is a string.

We use concatMap here, rather than normal map, since we want to generate a single list of objects [Obj] not a nested list of lists of lists of Objects: [[[Obj]]], and since we're running stoline on each String in the input, we need to collapse that structure as we traverse lolos.

We can clean up the above code (make it more haskelly) by making it point-free. \s -> stoline s is the same as stoline, so we could have:

stomap lolos = concatMap (\los -> concatMap stoline los) lolos

\los -> concatMap stoline los is the same as concatMap stoline, so we could reduce that to:

stomap lolos = concatMap (concatMap stoline) lolos

And we can drop the argument from both sides, giving us:

stomap = concatMap (concatMap stoline)

It may seem illegible at first, but to the experienced haskeller, this can read even more clearly than your original code - it's clear to me that this last version just combines the results of running stoline over a list of lists.