[Haskell-cafe] Polymorphic functions over string libraries

Sergey Vinokurov serg.foo at gmail.com
Mon Oct 27 22:09:09 UTC 2014


Hi Gonzaw,

Among other alternatives you could try using
http://hackage.haskell.org/package/ListLike package. It provides
similar interface to strings and text, but all functions operate on a
typeclass so they may be used with either Text or Strings. E.g.

import Data.Char
import Data.Text (Text)
import qualified Data.Text as T
import Data.ListLike (ListLike, ListLikeIO)
import qualified Data.ListLike as LL

transform :: String -> String
transform = map toUpper

transform' :: Text -> Text
transform' = T.map toUpper

onFile :: (ListLikeIO s c) => FilePath -> FilePath -> (s -> s) -> IO ()
onFile fileIn fileOut f = LL.readFile fileIn >>= LL.writeFile fileOut . f

main :: IO ()
main = do
  writeFile "foo" "hello world\n"
  onFile "foo" "bar" transform
  onFile "foo" "bar" transform'


On Mon, Oct 27, 2014 at 7:50 PM, Adam Bergmark <adam at bergmark.nl> wrote:
>
> I
> If you want to accept String and Text and ByteString your implicitly state
> that you do not make any assumptions about the encoding
>
> I think the most pragmatic (and perhaps even the most appropriate) solution
> is to simply to expose one set of functions working on one type.
>
> If you assume UTF-8 you should not accept a ByteString since it's not
> encoding aware. If you did you'd have to add documentation saying "this
> assumes that your bytestring contains valid UTF-8". Use Text instead since
> it's the best unicode-aware library available.
> If you don't make any assumptions about encoding, pick ByteString.
>
>
>
> On Sun, Oct 26, 2014 at 8:43 PM, John Lato <jwlato at gmail.com> wrote:
>>
>> This could be solved by SML-style modules, but as you mention, that's an
>> active area of research.  Class-based solutions, such as ListLike or the
>> newer mono-traversable, have been available for years.
>>
>> On Sun, Oct 26, 2014 at 9:18 AM, Kyle Marek-Spartz
>> <kyle.marek.spartz at gmail.com> wrote:
>>>
>>> This is one of the problems that an improved module language would solve
>>> such as the one in SML (Signatures and functors provide for this
>>> functionality). In Haskell-land, this is an active area of research. You
>>> may be interested in Backpack:
>>>
>>> http://plv.mpi-sws.org/backpack/
>>>
>>>
>>> gonzaw writes:
>>>
>>> > Hi.
>>> >
>>> > I was wondering what would be the best way to create a polymorphic
>>> > function
>>> > over any possible string library (Text, String, Bytestring, etc).
>>> >
>>> > For instance, imagine I have to read a file with text, transform this
>>> > text
>>> > in some way and output it to another file, or to the console.
>>> > If I wanted to use String, I'd just do this:
>>> > /
>>> > transform :: String -> String
>>> > main = readFile "input.txt" >>= writeFile "output.txt" . transform
>>> > /
>>> > But if I wanted to use Text instead, I'd have to use this:
>>> > /
>>> > import qualified Data.Text.IO as T
>>> >
>>> > transform :: Text -> Text
>>> > main = T.readFile "input.txt" >>= T.writeFile "output.txt" . transform
>>> > /
>>> > Idem for ByteString.
>>> >
>>> > I was wondering if there was a way to create these computations in a
>>> > generic
>>> > way, for any kind of string library, something like this:
>>> > /
>>> > class StringLibrary s where:
>>> > sReadFile :: FilePath -> IO s
>>> > sWriteFile :: FilePath -> s -> IO ()
>>> > ...
>>> > /
>>> > So then I'd just have this:
>>> > /
>>> > transform :: StringLibrary s => s -> s
>>> > main = sReadFile "input.txt" >>= sWriteFile "output.txt" . transform
>>> > /
>>> > Now I can perform the computation I want without being tied down to a
>>> > specific library. At times when I create some quick scripts, I find
>>> > myself
>>> > using one library (for example using String to get it finished more
>>> > quickly,
>>> > since I have less experience with the other ones), but find that it's
>>> > too
>>> > slow or has some problem that is solved by using one of the other
>>> > libraries.
>>> > Yet swapping from one to the other is more cumbersome than expected at
>>> > times.
>>> > In the example above, I could easily swap between them, just by forcing
>>> > the
>>> > compiler to typecheck to a specific one (for instance by changing the
>>> > type
>>> > of "transform"). Or if I wanted to, I could leave it as it is and
>>> > export it
>>> > as a library of my own.
>>> >
>>> > Is there a way to do something like this in Haskell, with existing
>>> > libraries?
>>> > In terms of using the string datatype as some sort of container of
>>> > characters, I think there are libraries like Lens and mono-traversable
>>> > that
>>> > allow you to do stuff like this. But I'm not too familiar with them (at
>>> > least using them in this way).
>>>
>>> --
>>> Kyle Marek-Spartz
>>> _______________________________________________
>>> Haskell-Cafe mailing list
>>> Haskell-Cafe at haskell.org
>>> http://www.haskell.org/mailman/listinfo/haskell-cafe
>>
>>
>>
>> _______________________________________________
>> Haskell-Cafe mailing list
>> Haskell-Cafe at haskell.org
>> http://www.haskell.org/mailman/listinfo/haskell-cafe
>>
>
>
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>


More information about the Haskell-Cafe mailing list