11

Is there a way to serialize (read/show) functions in Haskell?

For example given that:

:t (+1) 
(+1) :: Num a => a -> a

I wish to be able to have something like:

read "(+1)" :: Num a => a -> a

Unfortunately this throws an error:

Could not deduce (Read (a -> a)) arising from a use of `read'
from the context (Num a)
  bound by an expression type signature: Num a => a -> a
  at <interactive>:1:1-30
Possible fix:
  add (Read (a -> a)) to the context of
    an expression type signature: Num a => a -> a
  or add an instance declaration for (Read (a -> a))
In the expression: read "(+1)" :: Num a => a -> a
In an equation for `it': it = read "(+1)" :: Num a => a -> a
Roskoto
  • 1,722
  • 1
  • 16
  • 27
  • 3
    This is precisely an area where Lisp dialects shine. – Alexandre C. Aug 03 '11 at 12:50
  • 4
    An early variant of Haskell - Persistent Haskell - allowed functions to be serialized. I'm not sure if it was ever publicly available as it depended on technology developed at St. Andrews University (Scotland) for the persistent language Napier88. I've not read it closely, but the recent paper "Towards Haskell in the Cloud" seems to suggest work on serializing functions for distributed programming might have started in mainline GHC. – stephen tetley Aug 03 '11 at 13:11
  • 3
    There is indeed work on serializing functions going on for ghc, but it will be of a limited kind. – augustss Aug 03 '11 at 14:09

2 Answers2

10

It's (in general) impossible to show a function, but reading one is possible in principle if you have a Haskell compiler available at runtime.

augustss
  • 22,884
  • 5
  • 56
  • 93
  • 1
    Code samples? Of a Haskell compiler? – augustss Aug 03 '11 at 23:03
  • It’s certainly not impossible. You can `show` the original source, any compiler-internal representation, or preferably some machine-independent bytecode.This can be transferred and read-in again using the `dynamic-loader` or `plugins` package. … I didn’t say it would be pretty though. … Dynamic code loading and Haskell are kinda opposites of each other. – Evi1M4chine Dec 07 '16 at 05:19
  • 1
    Well, any Haskell function that converts a function to a string cannot be pure, because that would break referential transparency. But in the IO monad you could make something, but it will need compiler/runtime support. – augustss Dec 07 '16 at 05:46
7

You could use something like the plugins package to read code at runtime. Showing is, as augustss says, impossible though.

An example of how it could be used:

import System.Eval.Haskell

main = do
  mf <- eval "(+1) :: Int -> Int" []
  case mf of
    Just f -> print $ (f :: Int -> Int) 0
    _      -> putStrLn "Couldn't eval for some reason. :("
valderman
  • 8,365
  • 4
  • 22
  • 29