title: How can I parse a string to a function in Haskell?
body: <p>I want a function that looks something like this </p>
  
  <pre><code>readFunc :: String -&gt; (Float -&gt; Float)
  </code></pre>
  
  <p>which operates something like this</p>
  
  <pre><code>&gt;(readFunc "sin") (pi/2)
  &gt;1.0
  
  &gt;(readFunc "(+2)") 3.0
  &gt;5.0
  
  &gt;(readFunc "(\x -&gt; if x &gt; 5.0 then 5.0 else x)") 2.0
  &gt;2.0
  
  &gt;(readFunc "(\x -&gt; if x &gt; 5.0 then 5.0 else x)") 7.0
  &gt;5.0
  </code></pre>
  
  <p>The incredibly naive approach (note this must be compiled with <code>{-# LANGUAGE FlexibleContexts #-}</code>)</p>
  
  <pre><code>readFunc :: (Read (Float -&gt; Float)) =&gt; String -&gt; (Float -&gt; Float)
  readFunc s = read s
  </code></pre>
  
  <p>gives</p>
  
  <pre><code>No instance for (Read (Float -&gt; Float)) ...
  </code></pre>
  
  <p>Which makes sense since no such instance exists. I understand that I can parse the input string character by character by writing a map from <code>String</code> to <code>Float -&gt; Float</code> but I want to be able to parse at least the most common functions from prelude, and even that would be way more work than I want to commit to. Is there an easy way of doing this?</p>
  
  <h1>Just one solution using hint</h1>
  
  <pre><code>import Language.Haskell.Interpreter hiding (typeOf)
  import Data.Typeable (typeOf)
  
  data Domain = Dom Float Float Float Float Domain
              | SDom Float Float Float Float 
              deriving (Show, Read)
  
  --gets all the points that will appear in the domain
  points (SDom a b c d) m = [(x, y)|x &lt;- [a, a+m .. b], y &lt;- [c, c+m .. d]]
  points (Dom a b c d next) m = points next m ++ [(x, y)|x &lt;- [a, a+m .. b], y &lt;- [c, c+m .. d]]
  
  readFunc = do
      putStrLn "Enter a domain (as Dom x-min x-max y-min y-max subdomain, or, SDom x-min x-max y-min y-max)"
      domain' &lt;- getLine
      let domain = (read domain') :: Domain
      --
      putStrLn "Enter a mesh size"
      meshSize' &lt;- getLine
      let meshSize = (read meshSize') :: Float 
      --
      putStrLn "Enter an initial value function (as f(x,y))"
      func' &lt;- getLine
      values' &lt;- runInterpreter $ setImports["Prelude"] &gt;&gt;
                                  eval ("map (\\(x,y) -&gt; " ++ func' ++ ")" ++ show (points domain meshSize))
      let values = (\(Right v) -&gt; (read v)::([Float])) values'
  
      --the haskell expression being evaluated
      putStrLn $ ("map (\\(x,y) -&gt; " ++ func' ++ ")" ++ show (points domain meshSize)) 
  
      --prints the actual values
      putStrLn $ show values 
  
      --the type is indeed [float]
      putStrLn $ show $ typeOf values 
  </code></pre>