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