[Haskell-cafe] Extensible Effects & Multiple Operations

Justin Bailey jgbailey at gmail.com
Thu Jul 17 20:43:35 UTC 2014


I am playing around with the extensible-effects framework and cannot
figure out how to solve this problem. I am trying to define a set of
operations that only work after a file has been opened. For example,
reading a character from a file or detecting EOF.

My problem is I cannot figure out how to define one "runner" for my
Effect that can deal with operations with different result types. For
example, I would like my `readFrom` and `atEOF` operations to have the
following types:

  data OpenFile r v =  ... -- my "OpenFile" effect

  -- read a character from the file
  readFrom :: Eff r Char

  -- detect EOF
  atEOF :: Eff r Bool

And I would like to use this operations as follows (where I read a
byte from the file, check EOF, and return the concatenation of the two
values):

  main = do
     c <- runOpenFile "Setup.hs" (do
        a <- readFrom -- `a` has `Char` type
        eof <- atEOF -- `eof` has `Bool` type
        return $ [a] ++ show eof)
     putStrLn c

However, I cannot define a `runOpenFile` that compiles. For example,
this definition gives me "Overlapping Instance" errors:

  runOpenFile :: FilePath -> Eff (OpenFile v :> r) result -> IO result

The best I've come up with is to define a `Result` type that holds all
possible results:

   data Result = AtEOF Bool | ReadChar Char

The `Result` type then lets me put a single  type on the `OpenFile`
effect in `runOpenFile`:

  runOpenFile :: FilePath -> Eff (OpenFile Result :> r) result -> IO result

But that makes my `main` program pretty ugly, because I have to
deconstruct those result types each time:

  main = do
     c <- runOpenFile "Setup.hs" (do
        (ReadChar a) <- readFrom
        (AtEOF eof) <- atEOF
        return $ [a] ++ show eof)
     putStrLn c

Does anyone have suggestions?

Justin

p.s. The complete code (in a sort-of similar form) can be seen at
https://github.com/m4dc4p/ext-eff-sample/blob/master/src/OpenFile.hs


More information about the Haskell-Cafe mailing list