Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do i syntax in haskell

Tags:

haskell

Im trying to write a function that takes in a string and then returns the string as a list of string-words (like the words built-in function) and so far i've written

ord :: String -> [String]
ord [] = []
ord xs = let
    ys = groupBy (\x y -> y /= ' ') xs
    in filter (not . null) ys

I thougth this would get rid of the empty strings from the list but i only get this output

input:

ord  “aa b       c   -    dd” 

output:

["aa"," b"," "," "," "," "," "," "," c"," "," "," -"," "," "," "," dd"]

when this is the output i want:

[“aa”, ”b”, ”c”, ”-“, ”dd”]

I get the same result if i try and write

ord :: String -> [String]
ord [] = []
ord xs = filter (not . null) ys
    where
        ys = groupBy (\x y -> y /= ' ') xs

How do i re-write this code so that i rid the list of its empty strings? Or use the proper syntax? Im just learning Haskell and im still having trouble with the syntax...

like image 907
Mampenda Avatar asked Sep 13 '26 09:09

Mampenda


2 Answers

groupBy means that you put x and y in the same group, given the condition is satisfied. But here you group the two together, given y is not equal to a space.

You thus can alter your grouping predicate, and put x and y in the same group, given both are spaces, or non-spaces:

import Data.Char(isSpace)

ord :: String -> [String]
ord [] = []
ord xs = let
    ys = groupBy (\x y -> isSpace x == isSpace y) xs
    in filter (not . null) ys

or shorter:

import Data.Char(isSpace)
import Data.Function(on)

ord :: String -> [String]
ord [] = []
ord xs = let
    ys = groupBy (on (==) isSpace) xs
    in filter (not . null) ys

Now we retrieve:

Prelude Data.List> ord "aa b       c   -    dd"
["aa"," ","b","       ","c","   ","-","    ","dd"]

We of course still not obtain the expected result. In stead of filtering out empty strings, we can filter out strings that only contain spacing characters:

import Data.Char(isSpace)
import Data.Function(on)

ord :: String -> [String]
ord [] = []
ord xs = let
    ys = groupBy (on (==) isSpace) xs
    in filter (not . all isSpace) ys

We do not need to covert the empty case manually, since groupBy on an empty list produces an empty list, we can thus construct a one liner to do the processing:

import Data.Char(isSpace)
import Data.Function(on)

ord :: String -> [String]
ord = filter (not . all isSpace) . groupBy (on (==) isSpace)

Then we obtain the expected result:

Prelude Data.List Data.Char> ord "aa b       c   -    dd"
["aa","b","c","-","dd"]
like image 90
Willem Van Onsem Avatar answered Sep 16 '26 22:09

Willem Van Onsem


I wouldn't bother with groupBy at all here. In particular, there's no need to build lists of spaces just to throw them away. Let's start with a function that drops initial spaces and then grabs everything to the first space:

grab :: String -> (String, String)
grab = break isSpace . dropWhile isSpace

Note that the first component of grab xs will be empty if and only if all the elements of xs are spaces.

Now we can write

myWords :: String -> [String]
myWords xs = case grab xs of
  ([], _) -> []
  (beginning, end) -> beginning : myWords end
like image 43
dfeuer Avatar answered Sep 16 '26 23:09

dfeuer



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!