Home > Enterprise >  Haskell split, intercalate and lists
Haskell split, intercalate and lists

Time:06-06

I am trying to split a Data.Text into a [Text], run a function to the elements of that list, then unword them, or intercalate them. But the types do not match. Instead of a Text -> Text I get a [Text] -> [Text] function.

import Data.Text(Text, pack, unpack, intercalate, split)
f = split (\x-> x==' ') . intercalate (pack " ")
:t f 
--Prints for some reason: f :: [Text] -> [Text]

g = split (\x-> x==' ') . Data.Text.unwords
:t g
-- Prints again: g :: [Text] -> [Text]

How can I get a Text -> Text function?

CodePudding user response:

The type of your functions is:

split :: (Char -> Bool) -> Text -> [Text]
intercalate :: Text -> [Text] -> Text

If you were to write it without function composition the code would look like:

f :: Text -> Text
f text = intercalate (pack " ") (split (==' ') text)
-- or also: intercalate (pack " ") $ split (==' ') text

So what you want to do first is splitting and then intercalating. Look at how function composition is defined:

(.) :: (b -> c) -> (a -> b) -> a -> c
(.) f g = \x -> f (g x)

It takes two functions f and g and returns a function f(g(x)) applying first g and then f. So, when you write

f = split (\x-> x==' ') . intercalate (pack " ")

what you would get is:

f :: [Text] -> [Text]
f = \x -> intercalate (pack " ") (split (==' ') x)
-- first splitting and then intercalating

The code you want is:

f :: Text -> Text 
f = intercalate (pack " ") . split (== ' ')
-- equivalent to:
-- f = \x -> intercalate (pack " ") (split (== ' ') x)
-- where you first split and then intercalate

  • Related