Re: [Haskell-cafe] type/class question: toString

2007-11-07 Thread Nicholas Messenger
If you're willing to have an extra Typeable constraint, this does what you want:

 import Data.Typeable (Typeable, cast)
 import Data.Maybe (fromMaybe)

 toString :: (Show a, Typeable a) = a - String
 toString x = fromMaybe (show x) (cast x)

*Main toString blah
blah
*Main toString 1
1
*Main toString (Just 0.5)
Just 0.5

So Strings are just cast into the result.  Non-strings become Nothing,
which fromMaybe turns into (show x).

--
Nicholas Messenger
[EMAIL PROTECTED]


On Nov 6, 2007 4:23 PM, Graham Fawcett [EMAIL PROTECTED] wrote:
 On Nov 6, 2007 3:29 PM, Graham Fawcett [EMAIL PROTECTED] wrote:
  On Nov 6, 2007 2:21 PM, Jeff Polakow [EMAIL PROTECTED] wrote:
 Have you tried using -fglasgow-exts? That should enable all ghc
   extensions.

 If anyone's interested, I had best results when I added the flag
 -fallow-incoherent-instances. Without it, I could not handle numbers
 without declaring their types, e.g. 'toString (33 :: Int)' would work,
 but 'toString 33' would lead to:

 Ambiguous type variable `t' in the constraints:
   `ToString t'
 arising from use of `toString'
 at /home/graham/tmp/ToString.hs:13:15-25
   `Num t'
 arising from the literal `33'
 at /home/graham/tmp/ToString.hs:13:24-25
 Probable fix: add a type signature that fixes these type variable(s)

 Here's the code I ended up with.

 {-# OPTIONS -fglasgow-exts -fallow-overlapping-instances #-}
 {-# OPTIONS -fallow-incoherent-instances -fallow-undecidable-instances #-}

 module ToString (ToString(..)) where

 class Show a = ToString a  where toString :: a - String
 instance ToString Stringwhere toString s = s
 instance (Show a) = ToString a where toString s = show s


 Thanks to all who responded; I learned a lot from this.

 Graham

 ___
 Haskell-Cafe mailing list
 Haskell-Cafe@haskell.org
 http://www.haskell.org/mailman/listinfo/haskell-cafe

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Compile-time evaluation

2007-11-02 Thread Nicholas Messenger
{-# OPTIONS_GHC -fglasgow-exts -fno-monomorphism-restriction #-}

-- Many people ask if GHC will evaluate toplevel constants at compile
-- time, you know, since Haskell is pure it'd be great if those
-- computations could be done once and not use up cycles during
-- runtime.  Not an entirely bad idea, I think.
-- 
-- So I set about allowing just that: for arbitrary expressions to be
-- evaluated, and the expanded expression spliced into client code.
-- 
-- If you had some data in a file just out of convenience, you could say:
--  yourData = $(compileTimeIO $ parseFile $ readFile data.txt)
-- 
-- Or if you had an expensive computation that you want done at compile:
--  result = $(compileTimeEval $ expensiveComputation)
-- 
-- I would appreciate comments.  I wrote this completely blind with just
-- the TH and Generics haddocks, so if I'm doing something tremendously
-- stupid that can be improved, let me know. :)  Especially if you can
-- think of a less awkward way to go from Generics' data to TH
-- expressions than using 'showConstr'...
-- 
-- I wrote this with 6.6.1, in case there's any incompatibilities.  Copy/
-- paste this post into CompileTime.hs, load into ghci, :set -fth, and
-- futz around with the splices.
-- 
-- -- Nicholas Messenger (nmessenger at gmail.com, omnId on #haskell)

module CompileTime(compileTimeEval, compileTimeIO) where

import Data.Generics
import Language.Haskell.TH
import Control.Monad
import Data.Tree
import Data.Ratio

-- Expands a datum into an expression tree to be spliced into
-- client code.
compileTimeEval :: Data a = a - ExpQ
compileTimeEval = return . toExp

-- Runs the IO action and splices in the evaluated result datum.
compileTimeIO :: Data a = IO a - ExpQ
compileTimeIO = liftM toExp . runIO

-- Does the work. :)  toTree gets us a tree of constructors, so
-- we mostly just have to fold the tree with AppE, except for
-- TH's bizarre TupE.
toExp :: Data d = d - Exp
toExp = applyAll . toTree
 where
  applyAll (Node k args)
| isTuple k = TupE (map applyAll args)
| otherwise = foldl AppE k (map applyAll args)

  isTuple (ConE n) = all (==',') (nameBase n)
  isTuple _= False

-- Synonym to shorten the definition of exp below
type Ex a = a - Exp

-- Turns some datum into a tree of TH expressions representing
-- that datum.  The Exp at each node represents the constructor,
-- the subtrees are its arguments.
toTree :: Data d = d - Tree Exp
toTree x = Node (exp x) (gmapQ toTree x)
 where
  -- The various ways to turn a (Data d = d) into an
  -- Exp representing its constructor.
  any  = ConE . mkName . deparen . showConstr . toConstr
  char = LitE . CharL
  int  = sigged $ LitE . IntegerL . toInteger
  rat  = sigged $ LitE . RationalL . toRational
  sigged f x = SigE (f x) (ConT . mkName . show $ typeOf x)

  -- The above functions combined together for different types.
  -- This is what gives the constructor Exp at each Node.  There
  -- are definitely more types to cover that 'any' gets wrong...
  exp = any `extQ` (int::Ex Int)`extQ` (int::Ex Integer)
`extQ` char `extQ` (rat::Ex Float)
`extQ` (rat::Ex Double) `extQ` (rat::Ex Rational)

  -- Generics' showConstr puts parens around infix
  -- constructors.  TH's ConE doesn't like 'em.
  deparen s = (if last s == ')' then init else id) .
  (if head s == '(' then tail else id) $ s
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Compile-time evaluation

2007-11-02 Thread Nicholas Messenger
On 11/2/07, Robin Green [EMAIL PROTECTED] wrote:
 snip ...since
 there is a Template Haskell class for the concept of translating actual
 values into TH representations of those values called Lift... snip

There's a WHAT?!

*checks docs*

You're telling me all that horrendous pain in implementing toExp and
it already exists?!?

GRRAGGHHRAWWRRRAAGGGH!

*sob*

...

Ah, well, I learned me some Data.Generics anyway.  :3

-- Nicholas Messenger (nmessenger at gmail.com, omnId on #haskell)
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe