[Haskell-cafe] Type constructor variables no longer injective in GHC 7.2.1?
Hello Cafe, say we take these standard definitions: {-# LANGUAGE GADTs, TypeOperators, TypeFamilies, ScopedTypeVariables #-} data a :=: b where Refl :: a :=: a subst :: a :=: b - f a - f b subst Refl = id Then this doesn't work (error message at the bottom): inj1 :: forall f a b. f a :=: f b - a :=: b inj1 Refl = Refl But one can still construct it with a trick that Oleg used in the context of Leibniz equality: type family Arg fa type instance Arg (f a) = a newtype Helper fa fa' = Helper { runHelper :: Arg fa :=: Arg fa' } inj2 :: forall f a b. f a :=: f b - a :=: b inj2 p = runHelper (subst p (Helper Refl :: Helper (f a) (f a))) So, it seems to me that either rejecting inj1 is a bug (or at least an inconvenience), or GHC is for some reason justified in not assuming type constructor variables to be injective, and accepting inj2 is a bug. I guess it's the former, since type constructor variables can't range over type functions AFAIK. The error message for inj1 is: Could not deduce (a ~ b) from the context (f a ~ f b) bound by a pattern with constructor Refl :: forall a. a :=: a, in an equation for `inj1' at /tmp/inj.lhs:12:8-11 `a' is a rigid type variable bound by the type signature for inj1 :: (f a :=: f b) - a :=: b at /tmp/inj.lhs:12:3 `b' is a rigid type variable bound by the type signature for inj1 :: (f a :=: f b) - a :=: b at /tmp/inj.lhs:12:3 Expected type: a :=: b Actual type: a :=: a In the expression: Refl In an equation for `inj1': inj1 Refl = Refl Cheers, Daniel ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Deriving instances with GADTs
Hi, you can declare an instance instance Show (OrderType s o) where ... this makes sense since it means for every type s and o, OrderType s o is showable, which is vacuously true if (s,o) isn't in {Buy,Sell} x {Market, Limit} (because in that case, there /is/ no non-bottom value of type 'OrderType s o'). Obviously, this will make the newtype's 'deriving' clause work. Furthermore, you can use {-# LANGUAGE StandaloneDeriving #-} and write deriving instance Show (OrderType s o) (Standalone deriving works differently from a 'deriving' clause; the former generates the code regardless of how weird the type is and lets the typechecker decide. For your GADT, this succeeds). Cheers, Daniel Schüssler On 2011-August-04 Thursday 08:57:46 Tim Cowlishaw wrote: Hi all, I've been writing a DSL to describe securities orders, and after a lot of help from the kind folk of this list and #haskell have come up with the following implementation, using generalised algebraic data types: https://gist.github.com/1124621 Elsewhere in my application, I make use of the order type defined therein in the following newtype declaration: newtype OrderListLevel s = OrderListLevel {orders :: [Order s Limit]} deriving (Eq, Show) However, the 'deriving' clause here fails: src/Simulation/OrderList.hs:9:82: No instance for (Eq (Order s Limit)) arising from the 'deriving' clause of a data type declaration at src/Simulation/OrderList.hs:9:82-83 src/Simulation/OrderList.hs:9:86: No instance for (Show (Order s Limit)) arising from the 'deriving' clause of a data type declaration at src/Simulation/OrderList.hs:9:86-89 I don't fully understand this - the error is correct that there is no instance of either Eq or Show for (Order s Limit), however, instances are defined for Order Buy Limit and Order Sell Limit, and since these are the only possible types that a value can be constructed with (the type constructor is 'closed' over these types in some sense I guess), it seems to me that this should provide enough information to derive the Eq and Show instances. Am I making unreasonable expectations of ghci's instance-deriving mechanism here, or missing something obvious? Many thanks in advance, Tim ___ 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
Re: [Haskell-cafe] Data.Time
On 2011-June-27 Monday 10:15:28 Yitzchak Gale wrote: The biggest shortcoming, in my opinion, is that the documentation assumes that the reader is very familiar with the Haskell type system, and with viewing type signatures and instance lists as an integral and central part of the documentation. In particular, Haskell's standard numeric type classes and the conversion functions between them play a central role in the API of Data.Time. Making use of Haddock's recently added(?) support for comments on instance declaration would help a lot here, I think (even if it was just to draw attention to the Num/Integral/Real/Fractional instances). Before you undertake writing a whole new time library, why not try writing some improved documentation for Data.Time first? I got the impression that Tony's issue with Data.Time was the lack of some feature, not usability. Seems like the details that were omitted for the sake of constructiveness are quite relevant :) Cheers, Daniel ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type Constraints on Data Constructors
Correction: I meant data Baz f a = Baz (Foo f = f a) (Dropped the 'forall', which would make the inner 'f' have nothing to do with the type parameter 'f' of 'Baz') On 2011-June-09 Thursday 01:07:13 Daniel Schüssler wrote: Hello, you might be thinking of this type? {-# LANGUAGE Rank2Types #-} class Foo f where foo :: a - f a data Baz f a = Baz (forall f. Foo f = f a) instance Foo (Baz f) where foo a = Baz (foo a) Maybe the difference between Bar and Baz ist best explained by writing it with an explicit class dictionary for Foo: {-# LANGUAGE Rank2Types #-} data FooDict f = FooDict { foo :: forall a. a - f a } data Bar f a = Bar (FooDict f) (f a) data Baz f a = Baz (FooDict f - f a) fooDict_Baz :: FooDict (Baz f) fooDict_Baz = FooDict (\a - Baz (\d - foo d a)) -- fooDict_Bar :: FooDict (Bar f) -- fooDict_Bar = FooDict (\a - Bar ? ?) -- Doesn't work - you'd have to create a 'FooDict f' and a 'f a' out of just an 'a' Cheers, Daniel On 2011-June-08 Wednesday 20:45:56 Guy wrote: {- continuing discussion from beginners@ -} I have code such as class Foo f where foo :: a - f a data Bar f a = Foo f = Bar {bar :: f a} instance Foo (Bar f) where foo a = Bar $ foo a GHC insists that I put Foo f = on the instance declaration, even though the constructor for Bar implies this. Is there any reason why GHC cannot infer this constraint from the Bar constructor? One issue raised in the beginners thread is that undefined :: Bar f a is not Foo f, but as undefined cannot be evaluated, this would not appear to be a problem. ___ 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 mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type Constraints on Data Constructors
You could do something like this, but admittedly it appears slightly clunky: newtype Baz f a = Baz (Foo f = BazInner f a) data BazInner f a = BazInner { baz :: f a, baz2 :: f a } instance Foo (Baz f) where foo a = Baz (let b = foo a in BazInner b b) Cheers, Daniel On 2011-June-09 Thursday 15:25:40 Guy wrote: Can this be extended to records, without redundant repetition? data Baz f a = Baz {baz :: Foo f = f a, baz2 :: Foo f = f a} The type constraint for baz2 adds no information, as it's the same f as baz, but I can't leave it out. - Original Message - From: Daniel Schüssler dan...@gmx.de To: haskell-cafe@haskell.org Cc: Guy guytsalmave...@yahoo.com Sent: Thursday, 9 June 2011, 2:06 Subject: Re: [Haskell-cafe] Type Constraints on Data Constructors Hello, you might be thinking of this type? {-# LANGUAGE Rank2Types #-} class Foo f where foo :: a - f a data Baz f a = Baz (forall f. Foo f = f a) instance Foo (Baz f) where foo a = Baz (foo a) Maybe the difference between Bar and Baz ist best explained by writing it with an explicit class dictionary for Foo: {-# LANGUAGE Rank2Types #-} data FooDict f = FooDict { foo :: forall a. a - f a } data Bar f a = Bar (FooDict f) (f a) data Baz f a = Baz (FooDict f - f a) fooDict_Baz :: FooDict (Baz f) fooDict_Baz = FooDict (\a - Baz (\d - foo d a)) -- fooDict_Bar :: FooDict (Bar f) -- fooDict_Bar = FooDict (\a - Bar ? ?) -- Doesn't work - you'd have to create a 'FooDict f' and a 'f a' out of just an 'a' Cheers, Daniel ___ 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
Re: [Haskell-cafe] Type Constraints on Data Constructors
Hello, you might be thinking of this type? {-# LANGUAGE Rank2Types #-} class Foo f where foo :: a - f a data Baz f a = Baz (forall f. Foo f = f a) instance Foo (Baz f) where foo a = Baz (foo a) Maybe the difference between Bar and Baz ist best explained by writing it with an explicit class dictionary for Foo: {-# LANGUAGE Rank2Types #-} data FooDict f = FooDict { foo :: forall a. a - f a } data Bar f a = Bar (FooDict f) (f a) data Baz f a = Baz (FooDict f - f a) fooDict_Baz :: FooDict (Baz f) fooDict_Baz = FooDict (\a - Baz (\d - foo d a)) -- fooDict_Bar :: FooDict (Bar f) -- fooDict_Bar = FooDict (\a - Bar ? ?) -- Doesn't work - you'd have to create a 'FooDict f' and a 'f a' out of just an 'a' Cheers, Daniel On 2011-June-08 Wednesday 20:45:56 Guy wrote: {- continuing discussion from beginners@ -} I have code such as class Foo f where foo :: a - f a data Bar f a = Foo f = Bar {bar :: f a} instance Foo (Bar f) where foo a = Bar $ foo a GHC insists that I put Foo f = on the instance declaration, even though the constructor for Bar implies this. Is there any reason why GHC cannot infer this constraint from the Bar constructor? One issue raised in the beginners thread is that undefined :: Bar f a is not Foo f, but as undefined cannot be evaluated, this would not appear to be a problem. ___ 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] Question about the Monad instance for Iteratee (from the enumerator package)
Hello, for reference, said instance is: instance Monad m = Monad (Iteratee a m) where return x = yield x (Chunks []) m0 = f = ($ m0) $ fix $ \bind m - Iteratee $ runIteratee m = \r1 - case r1 of Continue k - return (Continue (bind . k)) Error err - return (Error err) Yield x (Chunks []) - runIteratee (f x) Yield x extra - runIteratee (f x) = \r2 - case r2 of Continue k - runIteratee (k extra) Error err - return (Error err) Yield x' _ - return (Yield x' extra) The thing I don't understand yet is the last line: Why is it OK to discard the leftover input from the (f x) Iteratee and yield just the leftover input from the first one (m0)? Cheers, Daniel ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Template Haskell question
Hello, assuming you mean avoiding the import of Data.Map in the module *using* x, you can use name quotations: A.hs: {-# LANGUAGE TemplateHaskell #-} module A where import Data.Map import Language.Haskell.TH x = varE 'empty B.hs: {-# LANGUAGE TemplateHaskell #-} module B where import A a = $x empty = -- No collision; the 'empty in A.hs becomes a fully qualified -- name according to what's in scope in A.hs, so 'a' has type -- Map k a To avoid the import in A.hs too: module A where import Language.Haskell.TH import Language.Haskell.TH.Syntax(mkNameG_v) x = varE (mkNameG_v containers-0.4.0.0 Data.Map empty) By the way, 'global' currently is a synonym for 'varE'; I guess it used to be something different and remains for backwards compatibility. Cheers, Daniel On 2011-April-17 Sunday 18:42:15 Alexey Karakulov wrote: I'm interested if it's possible to use functions from some module without explicitly importing it. In ghci it's done on the fly, like this: Prelude Data.Map.empty Loading package array-0.3.0.2 ... linking ... done. Loading package containers-0.4.0.0 ... linking ... done. fromList [] But without gchi it seems impossible. I have the file Test.hs: {-# LANGUAGE TemplateHaskell #-} module Test where import Language.Haskell.TH x :: ExpQ x = global $ mkName Data.Map.empty When I load it in ghci, all works: $ ghci -XTemplateHaskell Test.hs *Test $x Loading package pretty-1.0.1.2 ... linking ... done. Loading package array-0.3.0.2 ... linking ... done. Loading package containers-0.4.0.0 ... linking ... done. Loading package template-haskell ... linking ... done. fromList [] But when I try to use it from other module, it fails. File Main.hs: {-# LANGUAGE TemplateHaskell #-} module Main where import Test main = do print $x $ runhaskell Main.hs Main.hs:5:9: Not in scope: `Data.Map.empty' In the result of the splice: $x To see what the splice expanded to, use -ddump-splices In the first argument of `print', namely `$x' In the expression: print ($x) -- All the best, Alexey ___ 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] Computing the multiplication table of a group using the GHC inliner ; )
Hello, turns out that you can define the group operation of the symmetric group on 3 elements in this abstract way (via the isomorphism to the group of bijective functions from a three-element type to itself): s3mult g2 g1 = fromFun (toFun g2 . toFun g1) and convince GHC to compile it down to a nested case statement. It even somehow made the left multiplication with the identity non-strict. Just thought it's neat ;) $ ghc-core S3.hs -funfolding-use-threshold=64 ... -- identifiers manually un-qualified for readability s3mult = \ (g2_ahA :: S3) (g1_ahB :: S3) - case g2_ahA of _ { S3abc - g1_ahB; S3bca - case g1_ahB of _ { S3abc - S3bca; S3bca - S3cab; S3cab - S3abc; S3acb - S3bac; S3bac - S3cba; S3cba - S3acb }; S3cab - case g1_ahB of _ { S3abc - S3cab; S3bca - S3abc; S3cab - S3bca; S3acb - S3cba; S3bac - S3acb; S3cba - S3bac }; S3acb - case g1_ahB of _ { S3abc - S3acb; S3bca - S3cba; S3cab - S3bac; S3acb - S3abc; S3bac - S3cab; S3cba - S3bca }; S3bac - case g1_ahB of _ { S3abc - S3bac; S3bca - S3acb; S3cab - S3cba; S3acb - S3bca; S3bac - S3abc; S3cba - S3cab }; S3cba - case g1_ahB of _ { S3abc - S3cba; S3bca - S3bac; S3cab - S3acb; S3acb - S3cab; S3bac - S3bca; S3cba - S3abc } } -- inverse s3inv = \ (g_ahC :: S3) - case g_ahC of _ { S3abc - S3abc; S3bca - S3cab; S3cab - S3bca; S3acb - S3acb; S3bac - S3bac; S3cba - S3cba } --- end core --- --- source --- module S3 where -- | Symmetric group / permutation group on 3 elements data S3 = S3abc | S3bca | S3cab | S3acb | S3bac | S3cba deriving(Eq) -- | Returns an element of S3 satisfying the given predicate s3the :: (S3 - Bool) - S3 s3the p | p S3abc = S3abc | p S3acb = S3acb | p S3bac = S3bac | p S3bca = S3bca | p S3cba = S3cba | p S3cab = S3cab | otherwise = error s3the: no element satisfies the predicate data ABC = A | B | C deriving(Eq) toFun :: S3 - ABC - ABC toFun g = case g of S3abc - mkFun A B C S3bca - mkFun B C A S3cab - mkFun C A B S3acb - mkFun A C B S3bac - mkFun B A C S3cba - mkFun C B A where mkFun imA _ _ A = imA mkFun _ imB _ B = imB mkFun _ _ imC _ = imC fromFun :: (ABC - ABC) - S3 fromFun f = s3the (\g - toFun g A == f A toFun g B == f B) s3mult :: S3 - S3 - S3 s3mult g2 g1 = fromFun (toFun g2 . toFun g1) s3inv g = s3the (\g' - s3mult g' g == S3abc) ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] segfault when using ghc api
Hi, On 2011-February-27 Sunday 16:20:06 Edward Amsden wrote: Secondly, I'd like to get to a GHC session that just has, say, Prelude in scope so I can use dynCompileExpr with show etc, but I cannot figure out how to bring it into scope. The closest I got was to get GHC complaining that it was a package module. I don't know if setContext is the proper/best way to do it, but it seems to work: import GHC import GHC.Paths ( libdir ) import DynFlags ( defaultDynFlags ) import Module(stringToPackageId, mkModuleName) import Data.Dynamic(fromDynamic) import System.Environment evalString s = defaultErrorHandler defaultDynFlags $ do runGhc (Just libdir) $ do dflags - getSessionDynFlags setSessionDynFlags dflags setContext [] [ (mkModule (stringToPackageId base) (mkModuleName Prelude) ,Nothing) ] dyn - dynCompileExpr s return $ fromDynamic dyn main = do (s:_) - getArgs e - evalString s putStrLn $ maybe oops id e ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Linear programming in Haskell
On Thursday 18 February 2010 11:26:02 Ozgur Akgun wrote: I've no idea about the GLPK system. But, isn't it the case that you can transform any linear inequality into a linear equality and a slack (or excess) variable? Well yes, but the slack variables are constrained to be nonnegative, which isn't essentially different from having arbitrary inequalities (but it's convenient). The problem doesn't reduce to solving a system of linear equalities (as an illustration of how it's more tricky than linear equalities, the question of whether the problem is in P was settled quite recently, in 1972. (Recently when compared to classical linear algebra :))). Greetings, Daniel ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Linear programming in Haskell
Hello Alberto, Thank you! I don't have a problem calling for LP at hand right now, but some time ago I was looking for such a package. Now I know where to look next time :) Greetings, Daniel On Wednesday 24 February 2010 11:07:08 Alberto Ruiz wrote: I have uploaded to hackage an interface to the simplex algorithm based on GLPK. It is a very early version, it will probably have lots of problems. In the future I would like to add support for integer variables (MIP). Any suggestion is welcome. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] What is the meaning of tilde (~) symbol
On Sunday 14 February 2010 17:02:36 Henk-Jan van Tuyl wrote: The symbols that are not specified in a library can be found here: http://www.haskell.org/haskellwiki/Keywords Hoogle used to show links to this page, when a keyword was searched, but not anymore. This isn't Haskell 98 only, is it? :) *Adds type families, fundeps and the arcane arrow notation* -- Daniel ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Typeclasses for name punning (was: Re: I miss OO)
Hi all, On Wednesday 25 November 2009 22:46:42 Luke Palmer wrote: I feel like this should be qualified. Type classes are not for name punning ; you wouldn't use a type class for the method bark on types Tree and Dog. But if you have a well-defined *structure* that many types follow, then a type class is how you capture that. It sounds like you do have this structure in your example. Further, with typeclasses, you can write methods that are generic over any type with that structure. So: class Temporal a where time :: a - Time temporalOrder :: Temporal a = [a] - [a] temporalOrder = sortBy (comparing time) The ability to do this indicates why using them for punning is a bad idea. While I agree that this utility of typeclasses is lost if they are used for name punning, I'm still unconvinced that it is actively *harmful* to use classes for this lesser purpose :) I think punning is a worthwhile goal on its own, since I find myself wasting quite some thought on whether to prefix a record field name somehow, and if I do, what I should use as a short but sufficiently unique prefix. Greetings, Daniel ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Could someone teach me why we use Data.Monoid?
On Sunday 15 November 2009 13:05:08 Nicolas Pouillard wrote: Excerpts from Daniel Schüssler's message of Sun Nov 15 07:51:35 +0100 2009: Hi, Hi, Hi, -- Invariant 1: There are never two adjacent Lefts or two adjacent Rights [...] normalize (Left a0 : Left a1 : as) = Left (mappend a0 a1) : normalize as normalize (Right a0 : Right a1 : as) = Right (mappend a0 a1) : normalize as If you want to preserve your invariant, I think you should do : normalize (Left a0 : Left a1 : as) = normalize (Left (mappend a0 a1) : as) normalize (Right a0 : Right a1 : as) = normalize (Right (mappend a0 a1) : as) However, maybe it is correct if you only call normalize on (xs ++ ys) where xs and ys are already normalized so that you have only one point where you can break this invariant. Regards, You are right :) If `normalize' is meant to normalize arbitrary lists, we'd have to use your version. If OTOH we just want to normalize xs ++ ys, we shouldn't iterate over the whole list; it'd be better to use Data.Sequence and just consider the middle, as you said (I was thinking of free groups, where there can be more collapse, but in that case we'd need the analogue your version too). Greetings, Daniel ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] haskell-src-exts Question
Hi, On Friday 13 November 2009 21:08:42 Neil Mitchell wrote: In HLint I have a bracketing module, which has served me well. Please take any ideas you need from it - http://community.haskell.org/~ndm/darcs/hlint/src/HSE/Bracket.hs . In particular, given a fully bracketed expression, I can call transformBracket to transform the expression, not caring about brackets, in a way that guarantees the right brackets are put back. There is also needBracket and isAtom which are very useful. If you call descendBi (transformBracket Just) it will automatically bracket your term as much as is necessary. Funny, I did the opposite approach the other day (not saying either is better :)); that is: parenthesize everything while building the AST (with a wrapper for App) and then: deparenthesize :: (Data a) = a - a deparenthesize = everywhereBut isString (mkT goE `extT` goT) where isString x = typeOf x == typeOf (undefined :: String) goE (App (Paren (App e1 e2)) e3) = (App (App e1 e2) e3) goE (Paren (Paren e)) = Paren e goE (InfixApp e1 op'' (Paren (InfixApp e2 op' e3))) | op'' == op' , knownAssociative op'' = InfixApp e1 op'' (InfixApp e2 op' e3) goE (InfixApp (Paren (InfixApp e1 op'' e2)) op' e3) | op'' == op' , knownAssociative op'' = InfixApp (InfixApp e1 op'' e2) op' e3 goE x = x goT (TyApp (TyParen (TyApp t1 t2)) t3) = (TyApp (TyApp t1 t2) t3) -- add rule for function types too goT (TyParen (TyParen t)) = TyParen t goT x = x knownAssociative x = x `elem` [QVarOp (UnQual (Symbol .))] Though the infix thing doesn't quite work; apparently they still get printed with parens even if there are no parens in the AST? Or the rule just didn't match for some reason... -- Greetings, Daniel ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Could someone teach me why we use Data.Monoid?
Hi, - Product (a,b) and co-product (Either) of monoids the coproduct of monoids is actually a bit tricky. It could be implemented like this: -- | -- Invariant 1: There are never two adjacent Lefts or two adjacent Rights -- Invariant 2: No elements (Left mempty) or (Right mempty) allowed newtype Coprod m1 m2 = C [Either m1 m2] instance (Eq m1, Eq m2, Monoid m1, Monoid m2) = Monoid (Coprod m1 m2) where mempty = C [] mappend (C x1) (C x2) = C (normalize (x1 ++ x2)) normalize [] = [] normalize (Left a0 : as) | a0 == mempty = normalize as normalize (Right a0 : as) | a0 == mempty = normalize as normalize [a] = [a] normalize (Left a0 : Left a1 : as) = Left (mappend a0 a1) : normalize as normalize (Right a0 : Right a1 : as) = Right (mappend a0 a1) : normalize as normalize (a0:as) = a0 : normalize as inl x = normalize [Left x] inr x = normalize [Right x] fold :: (Monoid m1, Monoid m2, Monoid n) = (m1 - n) - (m2 - n) - Coprod m1 m2 - n fold k1 k2 = foldMap (either k1 k2) -- Alternative version, possibly more efficient? Represent directly as fold: -- newtype Coprod m1 m2 = C (forall n. Monoid n = (m1 - n) - (m2 - n) - n) instance Monoid (Coprod m1 m2) where mempty = C (\_ _ - mempty) mappend (C x) (C x') = C (\k1 k2 - mappend (x k1 k2) (x' k1 k2)) inl x = C (\k1 _ - k1 x) inr x = C (\_ k2 - k2 x) -- Question: in the mappend of the second version, we have a choice: We could also, when possible, multiply on the *inside*, that is *before* applying k1/k2: --- mappend (C x) (C x') = C (\k1 k2 - x (\m1 - x' (\m1' - k1 (mappend m1 m1') (\m2' - mappend (k1 m1) (k2 m2')) (\m2 - x' (\m1' - mappend (k2 m2) (k1 m1')) (\m2' - k2 (mappend m2 m2'))) --- Now I don't know what the efficiency implications of the two different versions are :) Apparently it depends on the relative costs of mappend in m1/m2 vs. n, and the cost of computing k1/k2? Greetings, Daniel ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Emacs: Haskell snippets for YASnippet
Hi List, this is rather trivial, but maybe someone else finds these useful: darcs get http://code.haskell.org/~daniels/haskell-snippets/ Especially the LANGUAGE ones have saved me quite some typing :) Additions welcome. Usage: If not already installed, get YASnippet: http://code.google.com/p/yasnippet/ and put this into your .emacs: (load-file some-path/haskell-snippets.el) to expand a snippet, just enter the macro string (these are listed in the haskell-snippets.el file) and press tab. If the snippet has holes, press tab again to jump to the next hole. Greetings, Daniel ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Emacs: Haskell snippets for YASnippet
Hi Deniz, Cool stuff, I will probably be using this! thanks :) In my opinion, the naming convention is a bit inconsistent. Extension snippets all begin with -x but imports begin with imp. I'd prefer seeing import snippets begin with -i and use names easier to remember, e.g. instead of impcms, use -istate and instead of impdm.Map use -imap, etc. At least consider it! :) Ah, the rationale behind the -x was that these are also GHC command line flags ;) But I also like -i better than imp. About the names: In one sense the current scheme is easier to remember because the abbreviation can be deduced from the module name. But I suppose you're right and state etc. are still easier to remember in practice, so feel free to send in a patch. And about the bot - ⊥ rule... Is ⊥ really valid Haskell? Well yes, but it's an operator name token, so valid haskell would be: x ⊥ y = x + y or (⊥) = undefined with this use as a constant you'd have to use the parentheses every time, so it probably isn't very useful indeed. Greetings, Daniel ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] What's this pattern called?
Hi, On Thursday 22 October 2009 09:47:32 Martijn van Steenbergen wrote: Bonjour café, data ExprF r = Add r r | Sub r r | Mul r r | Div r r | Num Int This is a well-known pattern that for example allows nice notation of morphisms. But what is it called? ... The multirec package calls this the pattern functor (more accurately, it generates a sum-of-products-like higher order functor whose fixed point is isomorphic to your family of types, and calls that the pattern functor). -- Greetings, Daniel ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] MTL vs Transformers?
On Tuesday 13 October 2009 02:46:29 Erik de Castro Lopo wrote: Hi all, I've just received the following error message: headers.hs:6:7: Could not find module `Control.Monad.Identity': it was found in multiple packages: transformers-0.1.4.0 mtl-1.1.0.2 I'm trying to use the Iteratee module which depends on Transformers but I use MTL in other stuff. Whats the preferred solution here? Erik Hi, alternative to ghc-pkg: {-# LANGUAGE -XPackageImports #-} module Blub where import mtl Control.Monad.State -- Daniel ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] rewrite rules
Hi Sjoerd, I don't know the cause of the problem, but if I add this rule, it works: {-# RULES inline_map forall g x. map g x = transform (. g) x -#} maybe, for whatever reason, the 'map' is inlined too late for the transform/transform rule to see it? Greetings, Daniel On Monday 22 June 2009 11:41:33 Sjoerd Visscher wrote: Hi all, I have a rewrite rule as follows: {-# RULES transform/transform forall (f::forall m. Monoid m = (a - m) - (b - m)) (g::forall m. Monoid m = (b - m) - (c - m)) (l::FMList c). transform f (transform g l) = transform (g.f) l #-} It fires on this code: print $ transform (. (*2)) (transform (. (+1)) (upto 10)) But it doesn't fire on this code: print $ map (*2) (map (+1) (upto 10))) with map g x = transform (. g) x and with or without {-# INLINE map #-}. What am I doing wrong? -- Sjoerd Visscher sjo...@w3future.com ___ 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
Re: [Haskell-cafe] how to #include files within parsec ... without unsafePerformIO?
Hi, ParsecT with m=IO? Your 'do' block would become: do i - getInput included - liftIO readI -- import Control.Monad.Trans for liftIO setInput included a - my_str setInput i b - my_str return $ a ++ //\n\n ++ b where readI = readFile experiment.hs Maybe I'm misunderstanding the problem. Greetings, Daniel On Thursday 18 June 2009 13:58:53 Leonard Siebeneicher wrote: Dear reader, I wonder whether there is a 'general' working solution to include files within a parsec parser. Without the need of unsafePerformIO. Appending an example program, using unsafePerformIO. Thanx for reading. Greetings, Leonard Siebeneicher --- Begin: experiment.hs --- import Text.ParserCombinators.Parsec import System.IO.Unsafe my_str :: Parser String my_str = many1 anyToken wrap_input :: Parser String - Parser String wrap_input p = do i - getInput setInput readI a - my_str setInput i b - my_str return $ a ++ //\n\n ++ b where {- Aaaah ... any solution without unsafePerformIO? -} readI = unsafePerformIO (readFile experiment.hs) main = case parse (wrap_input my_str) eintest of Left err - putStrLn Error raised Right ostr - putStrLn ostr --- End: experiment.hs --- ___ Thinking about a special type like data MyInclude = PlainText String | IncludeFile String the parser could generate [MyInclude] data, but it does not work generally. ___ 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
Re: [Haskell-cafe] fast Eucl. dist. - Haskell vs C
Hello! On Monday 18 May 2009 14:37:51 Kenneth Hoste wrote: I'm mostly interested in the range 10D to 100D is the dimension known at compile-time? Then you could consider Template Haskell. I wrote up some code for generating the vector types and vector subtraction/inner product below, HTH. One problem is that I'm using a typeclass and apparently you can't make {-# SPECIALISE #-} pragmas with TH, so let's hope it is automatically specialised by GHC. Greetings, Daniel TH.hs -- {-# LANGUAGE TemplateHaskell #-} {-# OPTIONS -fglasgow-exts #-} module TH where import Language.Haskell.TH import Control.Monad -- Non-TH stuff class InnerProductSpace v r | v - r where innerProduct :: v - v - r class AbGroup v where minus :: v - v - v euclidean x y = case minus x y of z - sqrt $! innerProduct z z -- TH noContext :: Q Cxt noContext = return [] strict :: Q Type - StrictTypeQ strict = liftM ((,) IsStrict) makeVectors :: Int -- ^ Dimension - Q Type -- ^ Component type, assumed to be a 'Num' - String -- ^ Name for the generated type - Q [Dec] makeVectors n ctyp name0 = do -- let's assume ctyp = Double, name = Vector for the comments -- generate names for the variables we will need xs - replicateM n (newName x) ys - replicateM n (newName y) let name = mkName name0 -- shorthands for arithmetic expressions; the first takes expressions, -- the others take variable names sumE e1 e2 = infixE (Just e1) [|(+)|] (Just e2) varDiffE e1 e2 = infixE (Just (varE e1)) [|(-)|] (Just (varE e2)) varProdE e1 e2 = infixE (Just (varE e1)) [|(*)|] (Just (varE e2)) conPat vars = conP name (fmap varP vars) -- data Vector = Vector !Double ... !Double theDataD = dataD noContext name [] -- no context, no params [normalC name (replicate n (strict ctyp))] [''Eq,''Ord,''Show] -- 'deriving' clause innerProdD = -- instance InnerProductSpace Vector Double where ... instanceD noContext ( conT ''InnerProductSpace `appT` conT name `appT` ctyp) -- innerProduct = ... [valD (varP 'innerProduct) (normalB -- \(Vector x1 x2 ... xn) (Vector y1 y2 ... yn) - (lamE [conPat xs, conPat ys] -- x1*y1 + + xn*yn + 0 (foldl sumE [|0|] $ zipWith varProdE xs ys) )) [] -- no 'where' clause ] abGroupD = instanceD noContext ( conT ''AbGroup `appT` conT name) -- minus = ... [valD (varP 'minus) (normalB -- \(Vector x1 x2 ... xn) (Vector y1 y2 ... yn) - (lamE [conPat xs, conPat ys] -- Vector (x1-y1) ... (xn-yn) (foldl appE (conE name) $ zipWith varDiffE xs ys) )) [] -- no 'where' clause ] sequence [theDataD,innerProdD,abGroupD] Main.hs -- {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE MultiParamTypeClasses #-} module Main where import TH $(makeVectors 3 [t|Double|] Vec3) main = print $ euclidean (Vec3 1 1 1) (Vec3 0 0 0) ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] fast Eucl. dist. - Haskell vs C
Hi, meh, I just realised that there is no sensible way to actually introduce/eliminate the generated types. I'm attaching a revised version with fromList/toList functions. Maybe the vector type should be polymorphic and be an instance of Functor, Monad and Foldable? But then we really depend on specialisation. Greetings, Daniel {-# LANGUAGE TemplateHaskell #-} {-# OPTIONS -fglasgow-exts #-} module TH where import Language.Haskell.TH import Control.Monad -- Non-TH stuff class InnerProductSpace v r | v - r where innerProduct :: v - v - r class AbGroup v where minus :: v - v - v class FromToList v r | v - r where fromList :: [r] - Maybe v toList :: v - [r] euclidean x y = case minus x y of z - sqrt $! innerProduct z z -- TH noContext :: Q Cxt noContext = return [] strict :: Q Type - StrictTypeQ strict = liftM ((,) IsStrict) makeVectors :: Int -- ^ Dimension - Q Type -- ^ Component type, assumed to be a 'Num' - String -- ^ Name for the generated type - Q [Dec] makeVectors n ctyp name0 = do -- let's assume ctyp = Double, name = Vector for the comments -- generate names for the variables we will need xs - replicateM n (newName x) ys - replicateM n (newName y) lst - newName list let name = mkName name0 -- shorthands for arithmetic expressions; the first takes expressions, -- the others take variable names sumE e1 e2 = infixE (Just e1) [|(+)|] (Just e2) varDiffE e1 e2 = infixE (Just (varE e1)) [|(-)|] (Just (varE e2)) varProdE e1 e2 = infixE (Just (varE e1)) [|(*)|] (Just (varE e2)) conPat vars = conP name (fmap varP vars) -- data Vector = Vector !Double ... !Double theDataD = dataD noContext name [] -- no context, no params [normalC name (replicate n (strict ctyp))] [''Eq,''Ord,''Show] -- 'deriving' clause innerProdD = -- instance InnerProductSpace Vector Double where ... instanceD noContext ( conT ''InnerProductSpace `appT` conT name `appT` ctyp) -- innerProduct = ... [valD (varP 'innerProduct) (normalB -- \(Vector x1 x2 ... xn) (Vector y1 y2 ... yn) - (lamE [conPat xs, conPat ys] -- x1*y1 + + xn*yn + 0 (foldl sumE [|0|] $ zipWith varProdE xs ys) )) [] -- no 'where' clause ] abGroupD = instanceD noContext ( conT ''AbGroup `appT` conT name) -- minus = ... [valD (varP 'minus) (normalB -- \(Vector x1 x2 ... xn) (Vector y1 y2 ... yn) - (lamE [conPat xs, conPat ys] -- Vector (x1-y1) ... (xn-yn) (foldl appE (conE name) $ zipWith varDiffE xs ys) )) [] -- no 'where' clause ] fromToListD = instanceD noContext ( conT ''FromToList `appT` conT name `appT` ctyp) [ funD 'fromList [ clause [listP $ fmap varP xs] (normalB ([|Just|] `appE` (foldl appE (conE name) $ fmap varE xs))) [] , clause [wildP] (normalB [|Nothing|]) [] -- wrong number of elements ] , funD 'toList [ clause [conPat xs] (normalB (listE (fmap varE xs))) []] ] sequence [theDataD,innerProdD,abGroupD,fromToListD] ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Classes: functional dependency (type - value)
Hello! The problem is that it's impossible to infer the SomeClass instance from the type SomeRole. If you do print role, which instance should it use? I can think of two ways around it: -- 1. (dummy parameter) -- data SomeRole a = Role1 | Role2 | Role3 deriving Show class SomeClass a where role :: SomeRole a data Foo = Foo data Bar = Bar instance SomeClass Foo where role = Role1 instance SomeClass Bar where role = Role2 main = do print (role :: SomeRole Foo) print (role :: SomeRole Bar) -- 2. (dummy argument) -- data SomeRole = Role1 | Role2 | Role3 deriving Show class SomeClass a where role :: a - SomeRole data Foo = Foo data Bar = Bar instance SomeClass Foo where role _ = Role1 instance SomeClass Bar where role _ = Role2 main = do print (role (undefined :: Foo)) print (role (undefined :: Bar)) -- On Sunday 10 May 2009 15:21:39 Belka wrote: Hello, communion people! I seek for your advice in a matter, where it's really hard for me to determine a good programming style. Here's the problem. I'm generalizing multiple authorization procedures to one, using class definition. (if of any interest, the code is in the end.) The problem essense is folowing: data SomeRole = Role1 | Role2 | Role3 class SomeClass a b c | a - b, c where f1 :: ... f2 :: ... ... fn :: ... role :: SomeRole -- -- here is the problem I want to have a fuctional dependency from a type a on a value of *role*, so that I could easily inspect the *role* from within any other class members. Is it possible? Or do I rougly violate some style traditions? Some real code using wished feature: --- data AuthentificationPurpose = JustValidateInput | JustGenerateForOutput | ValidateInputAndGenerateForOutput type AuthSucceded = Bool class AuthentificationStructure t_env t_realInput t_assumption t_keySet | t_realInput - t_assumptionInput, t_keySet where authentificationPurpose :: AuthentificationPurpose makeAssumption :: t_env - t_realInput - IO (Either ErrorMessage t_assumption) makeFinalKeySet :: (t_realInput, t_assumption) - t_keySet validateRealKeySet_with_Assumed :: t_realInput - t_keySet - Maybe ErrorMessage tryLogTheValidKey :: t_env - (t_realInput, t_assumption) - IO (Maybe ErrorMessage) tryLogTheAuthTry :: t_env - (t_realInput, t_assumption, AuthSucceded) - IO (Maybe ErrorMessage) authentificate :: AuthentificationStructure t_env t_realInput t_assumptionInput t_keySet = t_env - t_businessInput - IO (Either ErrorMessage (t_assumption, t_keySet)) authentificate env realInput = do err_or_assumption - makeAssumption env realInput case err_or_assumption of Left err_msg - return $ Left Error! Assumption maker failed. Lower level error message: ++ err_msg Just assumption - do key_set - makeFinalKeySet (realInput, assumption) err_or_keyset1 - case authentificationPurpose of JustGenerateForOutput - return $ Right key_set JustValidateInput - do mb_failure - validateRealKeySet_with_Assumed t_realInput key_set case mb_failure of Just err_msg - return $ Left Error! Invalid set of auth keys. Lower level error message: ++ err_msg Nothing - return $ Right key_set ValidateInputAndGenerateForOutput err_or_keyset2 - case err_or_keyset1 of Left err_msg - return err_or_keyset1 Right key_set - do mb_failure - tryLogTheValidKey env (realInput, assumption) case mb_failure of Just err_msg - return $ Left Error! Could not log valid key. Lower level error message: ++ err_msg Nothing - return err_or_keyset1 mb_failure - tryLogTheAuthTry env (realInput, assumption, isRight err_or_keyset2) case mb_failure of Just err_msg1 - case err_or_keyset2 of Left err_msg2 - return $ Left (1. ++ err_msg2 ++ \n2. ++ err_msg1) Right _ - return $ Left err_msg1 Nothing - case err_or_keyset2 of Left err_msg - return $ Left err_msg Right key_set - return $ Right (assumption, key_set) - Best regards, Belka ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org
Re: [Haskell-cafe] Re: Haskell Logo Voting has started!
Hi, Even worse, the buttons for moving items up and down are buggy - at least on my browser (Firefox 3.1 beta 2 on Linux). They sometimes reorder my other votes! Even assuming that the list box code is not buggy (which I now doubt), not being able to use the buttons makes this form almost unusable! I guess it works like this: Move down on an element X will make the /smallest/ change (with respect to the abstract ordering) that makes X worse than it's current value. This may require changing more than one number, for example if we have: (105: ) (106: A) (107: X,B) (108: C,D) (109: E ) (110: ) moving down X will result in either (105: A) (106: B) (107: X ) (108: C,D) (109: D ) (110: ) or equivalently (105: ) (106: A) (107: B ) (108: X ) (109: C,D) (110: D) of course, maybe you already know that but you're saying that it is doing this wrongly ;) Btw, I really think the logos should be on the same page as the voting form. Hotkeys for the buttons would be good too. It's usable though if you (incorrectly) consider the numbers as a sort of reverse star rating to make a O(n) pass, possibly finetuning later. Greetings, Daniel ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Haskell Logo Voting has started!
(correction of the example) (105: ) (106: A) (107: X,B) (108: C,D) (109: E ) (110: ) moving down X will result in either (105: A) (106: B) (107: X ) (108: C,D) (109: E ) (110: ) or equivalently (105: ) (106: A) (107: B ) (108: X ) (109: C,D) (110: E) ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Haskell Logo Voting has started!
On Tuesday 17 March 2009 21:03:21 Rick R wrote: QED Hmm? Maybe if confusingness was to be demonstrated, but not bugginess. Both possibilities will result in the same total preordering (defined by (x `betterThanOrEq` y) iff (numberInCombobox x = numberInCombobox y)), and (AFAIK) only this ordering matters for condorcet. Greetings, Daniel ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Parsing floating point numbers
Although maybeRead was proposed, I cannot find it: here's a replacement... http://hackage.haskell.org/packages/archive/safe/0.2/doc/html/Safe.html#v%3AreadMay Greetings, Daniel ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Basic problem in Haskell language design?
Hi, On Sunday 01 March 2009 14:26:42 Nicu Ionita wrote: [...] movesFromWord8s (f:t:ws) = (f, t) : movesFromWord8s ws moverFromWord8s _ = [] [...] Are there possible solutions or workarounds? for the particular problem of having to repeat the function name, you could use case: movesFromWord8s x = case x of f:t:ws - (f, t) : movesFromWord8s ws _ - [] (at the cost of one extra variable name :)) Greetings, Daniel ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ANN: convertible (first release)
Hello, it is a real code snippet, but I failed to include the necessary pragma (which is: {-# OPTIONS_GHC -fglasgow-exts #-} or {-# OPTIONS_GHC -XMagicHash #-} at the beginning of the file). the # suffix is for unboxed types: http://www.haskell.org/ghc/docs/latest/html/users_guide/primitives.html http://www.haskell.org/ghc/docs/latest/html/users_guide/syntax-extns.html#magic-hash Greetings, Daniel On Wednesday 11 February 2009 00:19:56 Dylan Tisdall wrote: Maybe I'm just a noob falling for someone's joke here, but I can't make that sample, or anything else I tried with # on the end of names, to compile with ghci. In the example below, I get a parse error at the line defining d2f. Is this a real code snippet? Cheers, Dylan On Feb 10, 2009, at 2:46 AM, Daniel Schüssler wrote: Hi, On Wednesday 28 January 2009 04:30:07 John Goerzen wrote: On Tue, Jan 27, 2009 at 09:41:30PM -0500, wren ng thornton wrote: I once again point out that realToFrac is *wrong* for converting from Float or Double. realToFrac (1/0::Float) ::Double 3.402823669209385e38 Yes, I understand what you are saying and agree with you. But there is nothing better in the standard library don't know whether you consider GHC as standard library, but if you do...: import GHC.Types import GHC.Prim -- | Double to Float d2f (D# d) = F# (double2Float# d) -- | Float to Double f2d (F# f) = D# (float2Double# f) ghci f2d (1/0) Infinity it :: Double :) -- Daniel ___ 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
Re: [Haskell-cafe] ANN: convertible (first release)
Hi, On Wednesday 28 January 2009 04:30:07 John Goerzen wrote: On Tue, Jan 27, 2009 at 09:41:30PM -0500, wren ng thornton wrote: I once again point out that realToFrac is *wrong* for converting from Float or Double. realToFrac (1/0::Float) ::Double 3.402823669209385e38 Yes, I understand what you are saying and agree with you. But there is nothing better in the standard library don't know whether you consider GHC as standard library, but if you do...: import GHC.Types import GHC.Prim -- | Double to Float d2f (D# d) = F# (double2Float# d) -- | Float to Double f2d (F# f) = D# (float2Double# f) ghci f2d (1/0) Infinity it :: Double :) -- Daniel ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe