I have turned the code into a library and put it up on github here:
http://github.com/kevinjardine/polyToMonoid
The library includes two versions of the function: ptm does not
require a termination function but does not allow partial evaluation
either. ctm is more composable (returning a
Hi Oleg,
I've found that if I also add two other slightly scary sounding
extensions: OverlappingInstances and IncoherentInstances, then I can
eliminate the unwrap function *and* use your type families trick to
avoid the outer type annotation.
My latest code is here:
{-# LANGUAGE
It also appears that we need type families to reconstruct the original
Haskell list system using polyToMonoid.
instance (a ~ a') = Monoidable a [a'] where
toMonoid a = [a]
testList = putStrLn $ show $ polyToMonoid (mempty :: [a]) a b c
Given this instance of Monoidable, you can put any
Hi Brandon,
True, when I replace [] with [], I get a different error message:
No instance for (PolyVariadic [[Char]] (WMonoid String))
which now looks a bit like the Int example. In both cases, GHC appears
to be unable to derive the appropriate instance of PolyVariadic. Why
this is so, but
And in fact in both cases, it appears that GHC is trying to derive the
*wrong* instances of PolyVariadic.
It should be deriving:
PolyVariadic Int (WMonoid Int)
not
PolyVariadic Int (WMonoid m)
and
PolyVariadic [String] (WMonoid [String])
not
PolyVariadic [String] (WMonoid String)
OK, upon further investigation, the problem is that GHC cannot in
general infer the return type of polyToMonoid despite the hint it is
given (the type signature of the first parameter).
If I write:
main = putStrLn $ show $ unwrap $ ((polyToMonoid [] True (Just
(5::Int))) :: WMonoid [String])
or
For anyone who's interested, the code I have now is:
{-# LANGUAGE TypeSynonymInstances, FlexibleInstances,
MultiParamTypeClasses #-}
module PolyTest where
import Data.Monoid
class Monoid m = Monoidable a m where
toMonoid :: a - m
squish :: Monoidable a m = m - a - m
squish m a = (m
It is interesting to see that the dummy parameters can actually be
replaced by:
mempty :: [String]
mempty :: String
mempty: Int
in my three examples and the code still compiles and gives the
expected results.
This suggests that a further simplification might be possible (ideally
in straight
For example, the notation can be reduced to:
poly([String],True () (Just (5::Int)))
using:
#define poly(TYPE,VALUES) ((polyToMonoid (mempty :: TYPE) VALUES) ::
TYPE)
which I think is as concise as it can get.
Kevin
On Oct 10, 1:47 pm, Kevin Jardine kevinjard...@gmail.com wrote:
It is
One final example to end with:
-- mixed type product example
instance Monoid Double where
mappend = (*)
mempty = (1.0) :: Double
instance Monoidable Int Double where
toMonoid = fromIntegral
instance Monoidable Double Double where
toMonoid = id
#define productOf(VALUES)
Sorry, I'm still catching up. I'm replying to first few messages.
instance Show a = Monoidable a [String] where
toMonoid a = [show a]
main = putStrLn $ unwrap $ polyToMonoid [] True () (Just (5::Int))
fails to compile.
The error message points to the first problem:
No instances
Hi Oleg,
Thank you for this wonderful detailed solution!
I was attempting to turn this into a small library and wanted to avoid
exporting unwrap.
I defined:
polyToMonoid' = unwrap . polyToMonoid
and then GHC told me:
No instance for (PolyVariadic a (WMonoid m))
arising from a use of
Hello Kevin,
2010/10/9 Kevin Jardine kevinjard...@gmail.com:
I was attempting to turn this into a small library and wanted to avoid
exporting unwrap.
I defined:
polyToMonoid' = unwrap . polyToMonoid
If you disable MonomorphismRestriction this definition typechecks just
fine. Alternatively,
Hi Bartek,
Yes, it compiles, but when I try to use polyToMonoid', it turns out
that this function is no longer polyvariadic, unlike the original
polyToMonoid .
This may be what Luke meant when he wrote you lose composability.
Even with the extra unwrap function I think that this is pretty cool,
Oleg,
Another puzzle is that:
instance Show a = Monoidable a String where
toMonoid a = show a
main = putStrLn $ unwrap $ polyToMonoid True () (Just (5::Int))
works just fine, but
instance Show a = Monoidable a [String] where
toMonoid a = [show a]
main = putStrLn $ unwrap $
Another example that also fails to compile (but I cannot see why):
import Data.PolyToMonoid
import Data.Monoid
instance Monoid Int where
mappend = (+)
mempty = 0
instance Monoidable Int Int where
toMonoid = id
main = putStrLn $ show $ unwrap $ polyToMonoid (0::Int) (1::Int)
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1
On 10/9/10 10:25 , Kevin Jardine wrote:
instance Show a = Monoidable a [String] where
toMonoid a = [show a]
main = putStrLn $ unwrap $ polyToMonoid [] True () (Just (5::Int))
fails to compile.
Why would that be? My understanding is that
Luke, I had no idea polyvariadic functions would be controversial.
Yes, in my original case the function would be trivial:
toMonoid k = [toString k]
I do prefer the less cluttered look. I think that
(poly value1 value2 value3)
is easier to follow when the values are all of related types (in
18 matches
Mail list logo