Re: [Haskell-cafe] link to section heading in Haddock

2012-06-09 Thread Simon Hengel
 After glancing through the haddock documentation and some googling, I
 can't tell if there's a supported
 way to link to a section heading in haddock documentation. Is there?

There are several things that could be of interest.

 - There is support for named anchors [1].  I guess this is your best
   bet for now.

   You could e.g. use

   Foo#g:1

   To link to the first section of module Foo.  Disadvantages:

 (a) the id is not stable, it changes when you add new sections
 before that section

 (b) you can't decide on the link text, it is always the module name

   If it is ok for you to just link to some portion of text instead of
   the section heading, you can insert a named anchor (e.g. #foobar#)
   and use that (e.g. Foo#foobar).  This solves (a), but not (b).


 - There is support for named links [2].  This is already implemented,
   not sure when it will hit the road.

 - There is a ticket for exactly what you are asking for [3].  But no
   work has been done on that yet.

Cheers,
Simon

[1] http://www.haskell.org/haddock/doc/html/ch03s08.html#id566440
[2] http://trac.haskell.org/haddock/ticket/190
[3] http://trac.haskell.org/haddock/ticket/193

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


Re: [Haskell-cafe] I don't understand how ST works

2012-06-09 Thread Nicu Ionita
Ok, the error was: I was using Control.Monad.ST.Lazy. Importing 
Control.Monad.ST compiles immediately without problem. (Is this because 
I'm using unboxed mutable vectors?)


Now, that's a little bit odd.

It's clear that the strict and lazy forms of ST are different types. But 
unfortunately they are named the same! So actually any error message 
from the compiler drives you crazy, because it's refering to another type.


Probably the reason to name the types with the same name is for easy 
interchangeability. But as we see, the types are not (always) 
interchangeable.


Anyway, now it compiles.

Thanks,
Nicu

Am 08.06.2012 23:15, schrieb Nicu Ionita:

Hi,

I created a gist with a minimal (still 111 lines) module:

https://gist.github.com/2898128

I still get the errors:

WhatsWrong.hs:53:5:
Couldn't match type `s' with `PrimState (ST s)'
  `s' is a rigid type variable bound by
  a type expected by the context: ST s [Move] at 
WhatsWrong.hs:48:21

In a stmt of a 'do' block: listMoves ml
In the second argument of `($)', namely
  `do { v - U.new maxMovesPerPos;
let ml = ...;
listMoves ml }'
In the expression:
  runST
  $ do { v - U.new maxMovesPerPos;
 let ml = ...;
 listMoves ml }

WhatsWrong.hs:65:44:
Couldn't match type `s' with `PrimState (ST s)'
  `s' is a rigid type variable bound by
  the type signature for nextPhaseOnlyCapts :: GenPhase s
  at WhatsWrong.hs:64:1
Expected type: U.MVector (PrimState (ST s)) Move
  Actual type: U.MVector s Move
In the return type of a call of `mlVec'
In the third argument of `genCapts', namely `(mlVec ml)'

Thanks,
Nicu

Am 08.06.2012 02:47, schrieb Silvio Frischknecht:

-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1


Now comes my question: in the impure values there is always that
s. I was thinking that the whole structure should have s as a
parameter:

Yes


data MList s = MList { mlVec :: MVector s Move, mlNextPh :: MList
-

ST s (Maybe (MList s)) }

you probably meant:

 data MList s = MList { ... , mlNextPh :: Mlist s -  ... }

Now I'm not sure about your exact problem since the following compiles
for me.

 import Data.Vector
 import Data.Vector.Mutable
 import Control.Monad.ST

 type Move = ()
 data MList s = MList {
 mvVec :: MVector s Move,
 mlNextPh :: MList s -  ST s (Maybe (MList s)) }

 splitMove :: MList s -  ST s (Maybe (Move, MList s))
 splitMove ml = do
 m- unsafeRead (mvVec ml) 0
 undefined

Something you always have to watch out for when dealing with ST is not
to return something that depends on s in the last statement (the one
you use runST on). In other words, if you want to return a vector you
have to freeze it, so it's not mutable anymore.

If you still can't figure it out paste some complete example that
doesn't work.

silvio
-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iQIcBAEBAgAGBQJP0Uu5AAoJEDLsP+zrbatWKFoP+wYdmAwO3aKPIibOydDwPlcu
GmwWLCDoylhBsA1swskPGZTlBevFFeS0kzDMAhZ2dtR18HHf0TVLFCL6mljgQGhu
YLsT8a2Y5eepPd7CC0wHD7qLH0t6ln/urRhWNnVEGryVHmsIDCBzuKBzopshaaOm
8awNeEbmZApki193r/YJ21Zsxidx4N2tSGCd712ka9Wr7l19RzBukonTy/wNCTtN
1sj54xCKap3MpnQe4L68nep6WjMovnwn5ucPWlouPP5N99/2umiEPDwX3y9moD/Q
VkbYe0HzZtvSX7JJaDM/hJ2dWKHsg5CLdO/aW7Uz3HttTy0/FmvwhxaNAzkmQimw
L4uakvyuw1EJuSAwB5XRfeUL6LDpka165jb8V8Iy2gjYg3aGMwf9VVmObjEAA93s
nvQd+iH1lDe38cbfz8dfQdTakDVYtFNnYL+kXIF1Z7DiS25IThtS0RJRH//E+CZg
MpOtW2LBfa3vwP9NqVryGTAhWFtWHXOtpXfCXOa0+pQNn1zHkTXtIDJ4XoT5qkmd
6GDwFyGfkPZO01qNMoXwj/wBz/eaSa4Vj0qb73jNdNH2MbJ13Ws9Jlp4jwcxbG4a
m/fYV0/6LmPEiV8H9+4cG8nhUP2ie2DJqo8tzdjiaZ7C7TEym9jd6gsljMQ8qiAG
Q7aAmMed/DBlY/Anh2xY
=X9CL
-END PGP SIGNATURE-



___
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] I don't understand how ST works

2012-06-09 Thread Yves Parès
Oh my god, that was it?
I looked at your code for half an hour, and I've never thought about
that... That is really misleading.
So vector forces you to use strict ST? (That's right:
http://hackage.haskell.org/packages/archive/primitive/0.4.1/doc/html/Control-Monad-Primitive.html#t:PrimMonadshows
that only strict ST has a MonadPrime instance)

It's another plea against the sames names/interface in different modules
pattern, that vector, ST, State, ByteString suffer from.
This (the error messages being misleading), as well as the document being
hard to read (because you never know which type is mentionned, you have to
see to check at the module from which the type comes. And even with that,
it's just a matter of convention: for instance Control.Monad.State exports
the lazy version, but Control.Monad.ST exports the strict one (so that the
default version is closer to IO's behaviour).

I really prefer the approach taken by repa 3: one data family, generic
functions for every flavour and some specific functions for each flavour.
It's not perfect (not standard for instance), but I think such an approach
should be priviledged in the future, it makes things much clearer, and
enable you to choose between working generically (on 'Stuff a' types) or
specifically (either only on 'Stuff Strict' or only on 'Stuff Lazy').
I would be interested to know if someone has other ideas in that respect in
mind.


2012/6/9 Nicu Ionita nicu.ion...@acons.at

 Ok, the error was: I was using Control.Monad.ST.Lazy. Importing
 Control.Monad.ST compiles immediately without problem. (Is this because
 I'm using unboxed mutable vectors?)

 Now, that's a little bit odd.

 It's clear that the strict and lazy forms of ST are different types. But
 unfortunately they are named the same! So actually any error message from
 the compiler drives you crazy, because it's refering to another type.

 Probably the reason to name the types with the same name is for easy
 interchangeability. But as we see, the types are not (always)
 interchangeable.

 Anyway, now it compiles.

 Thanks,
 Nicu

 Am 08.06.2012 23:15, schrieb Nicu Ionita:

  Hi,

 I created a gist with a minimal (still 111 lines) module:

 https://gist.github.com/**2898128 https://gist.github.com/2898128

 I still get the errors:

 WhatsWrong.hs:53:5:
Couldn't match type `s' with `PrimState (ST s)'
  `s' is a rigid type variable bound by
  a type expected by the context: ST s [Move] at
 WhatsWrong.hs:48:21
In a stmt of a 'do' block: listMoves ml
In the second argument of `($)', namely
  `do { v - U.new maxMovesPerPos;
let ml = ...;
listMoves ml }'
In the expression:
  runST
  $ do { v - U.new maxMovesPerPos;
 let ml = ...;
 listMoves ml }

 WhatsWrong.hs:65:44:
Couldn't match type `s' with `PrimState (ST s)'
  `s' is a rigid type variable bound by
  the type signature for nextPhaseOnlyCapts :: GenPhase s
  at WhatsWrong.hs:64:1
Expected type: U.MVector (PrimState (ST s)) Move
  Actual type: U.MVector s Move
In the return type of a call of `mlVec'
In the third argument of `genCapts', namely `(mlVec ml)'

 Thanks,
 Nicu

 Am 08.06.2012 02:47, schrieb Silvio Frischknecht:

 -BEGIN PGP SIGNED MESSAGE-
 Hash: SHA1

  Now comes my question: in the impure values there is always that
 s. I was thinking that the whole structure should have s as a
 parameter:

 Yes

  data MList s = MList { mlVec :: MVector s Move, mlNextPh :: MList
 -

 ST s (Maybe (MList s)) }

 you probably meant:

 data MList s = MList { ... , mlNextPh :: Mlist s -  ... }

 Now I'm not sure about your exact problem since the following compiles
 for me.

 import Data.Vector
 import Data.Vector.Mutable
 import Control.Monad.ST

 type Move = ()
 data MList s = MList {
 mvVec :: MVector s Move,
 mlNextPh :: MList s -  ST s (Maybe (MList s)) }

 splitMove :: MList s -  ST s (Maybe (Move, MList s))
 splitMove ml = do
 m- unsafeRead (mvVec ml) 0
 undefined

 Something you always have to watch out for when dealing with ST is not
 to return something that depends on s in the last statement (the one
 you use runST on). In other words, if you want to return a vector you
 have to freeze it, so it's not mutable anymore.

 If you still can't figure it out paste some complete example that
 doesn't work.

 silvio
 -BEGIN PGP SIGNATURE-
 Version: GnuPG v1.4.11 (GNU/Linux)
 Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

 iQIcBAEBAgAGBQJP0Uu5AAoJEDLsP+**zrbatWKFoP+**wYdmAwO3aKPIibOydDwPlcu
 GmwWLCDoylhBsA1swskPGZTlBevFFe**S0kzDMAhZ2dtR18HHf0TVLFCL6mljg**QGhu
 YLsT8a2Y5eepPd7CC0wHD7qLH0t6ln**/**urRhWNnVEGryVHmsIDCBzuKBzopsha**aOm
 8awNeEbmZApki193r/**YJ21Zsxidx4N2tSGCd712ka9Wr7l19**RzBukonTy/wNCTtN
 1sj54xCKap3MpnQe4L68nep6WjMovn**wn5ucPWlouPP5N99/**2umiEPDwX3y9moD/Q
 

[Haskell-cafe] ANN: lucienne-0.0.1

2012-06-09 Thread Alexander Bau
Hi,

some time ago I wrote lucienne[1] using the happstack framework:

 Lucienne is a simple server side feed aggregator/reader that helps 
 you managing your subscribed feeds. It provides multi user support 
 using basic access authentication. A running mongoDB serves as
 database backend.

For more information, check [1] and [2].

Best regards,

Alex

[1] http://hackage.haskell.org/package/lucienne
[2] http://www.imn.htwk-leipzig.de/~abau/lucienne


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


[Haskell-cafe] ANNOUNCE: optparse-applicative 0.0.1

2012-06-09 Thread Paolo Capriotti
I'm pleased to announce the release of version 0.0.1 of
[optparse-applicative][1], a
library for writing command line option parsers in Applicative style.

You can find an introduction and tutorial on the [github page][2], and an
explanation of the internals on [my blog][3].

 [1]: http://hackage.haskell.org/package/optparse-applicative
 [2]: https://github.com/pcapriotti/optparse-applicative
 [3]: http://paolocapriotti.com/blog/2012/04/27/applicative-option-parser/

BR,
Paolo

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


Re: [Haskell-cafe] Have you seen this functor/contrafunctor combo?

2012-06-09 Thread Edward Kmett
Here is a considerably longer worked example using the analogy to J,
borrowing heavily from Wadler:

As J, this doesn't really add any power, but perhaps when used with
non-representable functors like Equivalence/Comparison you can do something
more interesting.

-- Used for Hilbert
{-# LANGUAGE DefaultSignatures, TypeOperators #-}

-- Used for Representable
{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, FlexibleContexts,
FlexibleInstances #-}

module Search where

import Control.Applicative
import Data.Function (on)
import Data.Functor.Contravariant
import GHC.Generics -- for Hilbert

newtype Search f a = Search { optimum :: f a - a }

instance Contravariant f = Functor (Search f) where
  fmap f (Search g) = Search $ f . g . contramap f

instance Contravariant f = Applicative (Search f) where
 pure a = Search $ \_ - a
 Search fs * Search as = Search $ \k -
   let go f = f (as (contramap f k))
   in  go (fs (contramap go k))

instance Contravariant f = Monad (Search f) where
  return a = Search $ \_ - a
  Search ma = f = Search $ \k -
optimum (f (ma (contramap (\a - optimum (f a) k) k))) k

class Contravariant f = Union f where
  union :: Search f a - Search f a - Search f a

instance Union Predicate where
  union (Search ma) (Search mb) = Search $ \ p - case ma p of
a | getPredicate p a - a
  | otherwise- mb p

instance Ord r = Union (Op r) where
  union (Search ma) (Search mb) = Search $ \ f - let
  a = ma f
  b = mb f
in if getOp f a = getOp f b then a else b

both :: Union f = a - a - Search f a
both = on union pure

fromList :: Union f = [a] - Search f a
fromList = foldr1 union . map return

class Contravariant f = Neg f where
  neg :: f a - f a

instance Neg Predicate where
  neg (Predicate p) = Predicate (not . p)

instance Num r = Neg (Op r) where
  neg (Op f) = Op (negate . f)

pessimum :: Neg f = Search f a - f a - a
pessimum m p = optimum m (neg p)

forsome :: Search Predicate a - (a - Bool) - Bool
forsome m p = p (optimum m (Predicate p))

forevery :: Search Predicate a - (a - Bool) - Bool
forevery m p = p (pessimum m (Predicate p))

member :: Eq a = a - Search Predicate a - Bool
member a x = forsome x (== a)

each :: (Union f, Bounded a, Enum a) = Search f a
each = fromList [minBound..maxBound]

bit :: Union f = Search f Bool
bit = fromList [False,True]

cantor :: Union f = Search f [Bool]
cantor = sequence (repeat bit)

least :: (Int - Bool) - Int
least p = head [ i | i - [0..], p i ]

infixl 4 --
(--) :: Bool - Bool - Bool
p -- q = not p || q

fan :: Eq r = ([Bool] - r) - Int
fan f = least $ \ n -
  forevery cantor $ \x -
forevery cantor $ \y -
  (take n x == take n y) -- (f x == f y)

-- a length check that can handle infinite lists
compareLength :: [a] - Int - Ordering
compareLength xs n = case drop (n - 1) xs of
   []  - LT
   [_] - EQ
   _   - GT

-- Now, lets leave Haskell 98 behind

-- Using the new GHC generics to derive versions of Hilbert's epsilon

class GHilbert t where
  gepsilon :: Union f = Search f (t a)

class Hilbert a where
  -- http://en.wikipedia.org/wiki/Epsilon_calculus
  epsilon :: Union f = Search f a
  default epsilon :: (Union f, GHilbert (Rep a), Generic a) = Search f a
  epsilon = fmap to gepsilon

instance GHilbert U1 where
  gepsilon = return U1

instance (GHilbert f, GHilbert g) = GHilbert (f :*: g) where
  gepsilon = liftA2 (:*:) gepsilon gepsilon

instance (GHilbert f, GHilbert g) = GHilbert (f :+: g) where
  gepsilon = fmap L1 gepsilon `union` fmap R1 gepsilon

instance GHilbert a = GHilbert (M1 i c a) where
  gepsilon = fmap M1 gepsilon

instance Hilbert a = GHilbert (K1 i a) where
  gepsilon = fmap K1 epsilon

instance Hilbert ()
instance (Hilbert a, Hilbert b) = Hilbert (a, b)
instance (Hilbert a, Hilbert b, Hilbert c) = Hilbert (a, b, c)
instance (Hilbert a, Hilbert b, Hilbert c, Hilbert d) =
  Hilbert (a, b, c, d)
instance (Hilbert a, Hilbert b, Hilbert c, Hilbert d, Hilbert e) =
  Hilbert (a, b, c, d, e)
instance Hilbert Bool
instance Hilbert Ordering
instance Hilbert a = Hilbert [a]
instance Hilbert a = Hilbert (Maybe a)
instance (Hilbert a, Hilbert b) = Hilbert (Either a b)
instance Hilbert Char where
  epsilon = each
instance (Union f, Hilbert a) = Hilbert (Search f a) where
  epsilon = fmap fromList epsilon

search :: (Union f, Hilbert a) = f a - a
search = optimum epsilon

find :: Hilbert a = (a - Bool) - a
find = optimum epsilon . Predicate

every :: Hilbert a = (a - Bool) - Bool
every = forevery epsilon

exists :: Hilbert a = (a - Bool) - Bool
exists = forsome epsilon

-- and MPTCs/Fundeps to define representable contravariant functors:

class Contravariant f = Representable f r | f - r where
  represent :: f a - a - r
  tally :: (a - r) - f a

instance Representable (Op r) r where
  represent (Op f) = f
  tally = Op

instance Representable Predicate Bool where
  represent (Predicate p) = p
  tally = Predicate

supremum :: Representable f r = Search f a - (a - r) - 

Re: [Haskell-cafe] Have you seen this functor/contrafunctor combo?

2012-06-09 Thread Edward Kmett
As an aside, the Union constraint on epsilon/gepsilon is only needed for
the :+: case, you can search products just fine with any old contravariant
functor, as you'd expect given the existence of the Applicative.

-Edward

On Sat, Jun 9, 2012 at 6:28 PM, Edward Kmett ekm...@gmail.com wrote:

 Here is a considerably longer worked example using the analogy to J,
 borrowing heavily from Wadler:

 As J, this doesn't really add any power, but perhaps when used with
 non-representable functors like Equivalence/Comparison you can do something
 more interesting.

 -- Used for Hilbert
 {-# LANGUAGE DefaultSignatures, TypeOperators #-}

 -- Used for Representable
 {-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, FlexibleContexts,
 FlexibleInstances #-}

 module Search where

 import Control.Applicative
 import Data.Function (on)
 import Data.Functor.Contravariant
 import GHC.Generics -- for Hilbert

 newtype Search f a = Search { optimum :: f a - a }

 instance Contravariant f = Functor (Search f) where
   fmap f (Search g) = Search $ f . g . contramap f

 instance Contravariant f = Applicative (Search f) where
  pure a = Search $ \_ - a
  Search fs * Search as = Search $ \k -
let go f = f (as (contramap f k))
in  go (fs (contramap go k))

 instance Contravariant f = Monad (Search f) where
   return a = Search $ \_ - a
   Search ma = f = Search $ \k -
 optimum (f (ma (contramap (\a - optimum (f a) k) k))) k

 class Contravariant f = Union f where
   union :: Search f a - Search f a - Search f a

 instance Union Predicate where
   union (Search ma) (Search mb) = Search $ \ p - case ma p of
 a | getPredicate p a - a
   | otherwise- mb p

 instance Ord r = Union (Op r) where
   union (Search ma) (Search mb) = Search $ \ f - let
   a = ma f
   b = mb f
 in if getOp f a = getOp f b then a else b

 both :: Union f = a - a - Search f a
 both = on union pure

 fromList :: Union f = [a] - Search f a
 fromList = foldr1 union . map return

 class Contravariant f = Neg f where
   neg :: f a - f a

 instance Neg Predicate where
   neg (Predicate p) = Predicate (not . p)

 instance Num r = Neg (Op r) where
   neg (Op f) = Op (negate . f)

 pessimum :: Neg f = Search f a - f a - a
 pessimum m p = optimum m (neg p)

 forsome :: Search Predicate a - (a - Bool) - Bool
 forsome m p = p (optimum m (Predicate p))

 forevery :: Search Predicate a - (a - Bool) - Bool
 forevery m p = p (pessimum m (Predicate p))

 member :: Eq a = a - Search Predicate a - Bool
 member a x = forsome x (== a)

 each :: (Union f, Bounded a, Enum a) = Search f a
 each = fromList [minBound..maxBound]

 bit :: Union f = Search f Bool
 bit = fromList [False,True]

 cantor :: Union f = Search f [Bool]
 cantor = sequence (repeat bit)

 least :: (Int - Bool) - Int
 least p = head [ i | i - [0..], p i ]

 infixl 4 --
 (--) :: Bool - Bool - Bool
 p -- q = not p || q

 fan :: Eq r = ([Bool] - r) - Int
 fan f = least $ \ n -
   forevery cantor $ \x -
 forevery cantor $ \y -
   (take n x == take n y) -- (f x == f y)

 -- a length check that can handle infinite lists
 compareLength :: [a] - Int - Ordering
 compareLength xs n = case drop (n - 1) xs of
[]  - LT
[_] - EQ
_   - GT

 -- Now, lets leave Haskell 98 behind

 -- Using the new GHC generics to derive versions of Hilbert's epsilon

 class GHilbert t where
   gepsilon :: Union f = Search f (t a)

 class Hilbert a where
   -- http://en.wikipedia.org/wiki/Epsilon_calculus
   epsilon :: Union f = Search f a
   default epsilon :: (Union f, GHilbert (Rep a), Generic a) = Search f a
   epsilon = fmap to gepsilon

 instance GHilbert U1 where
   gepsilon = return U1

 instance (GHilbert f, GHilbert g) = GHilbert (f :*: g) where
   gepsilon = liftA2 (:*:) gepsilon gepsilon

 instance (GHilbert f, GHilbert g) = GHilbert (f :+: g) where
   gepsilon = fmap L1 gepsilon `union` fmap R1 gepsilon

 instance GHilbert a = GHilbert (M1 i c a) where
   gepsilon = fmap M1 gepsilon

 instance Hilbert a = GHilbert (K1 i a) where
   gepsilon = fmap K1 epsilon

 instance Hilbert ()
 instance (Hilbert a, Hilbert b) = Hilbert (a, b)
 instance (Hilbert a, Hilbert b, Hilbert c) = Hilbert (a, b, c)
 instance (Hilbert a, Hilbert b, Hilbert c, Hilbert d) =
   Hilbert (a, b, c, d)
 instance (Hilbert a, Hilbert b, Hilbert c, Hilbert d, Hilbert e) =
   Hilbert (a, b, c, d, e)
 instance Hilbert Bool
 instance Hilbert Ordering
 instance Hilbert a = Hilbert [a]
 instance Hilbert a = Hilbert (Maybe a)
 instance (Hilbert a, Hilbert b) = Hilbert (Either a b)
 instance Hilbert Char where
   epsilon = each
 instance (Union f, Hilbert a) = Hilbert (Search f a) where
   epsilon = fmap fromList epsilon

 search :: (Union f, Hilbert a) = f a - a
 search = optimum epsilon

 find :: Hilbert a = (a - Bool) - a
 find = optimum epsilon . Predicate

 every :: Hilbert a = (a - Bool) - Bool
 every = forevery epsilon

 exists :: Hilbert a = (a - Bool) - Bool
 exists = forsome 

Re: [Haskell-cafe] Fundeps and overlapping instances

2012-06-09 Thread Gábor Lehel
On Tue, Jun 5, 2012 at 2:25 PM, Gábor Lehel illiss...@gmail.com wrote:
 The encoded version would be:

 instance (f a b) = FMap f (HJust a) (HJust b)
  where type f :$: (HJust a) = HJust b

 and I think this actually demonstrates a *different* limitation, namely that

 The RHS of an associated type declaration mentions type variable `b'
   All such variables must be bound on the LHS

 which means that the standard encoding doesn't work for this case.

From a reddit comment[1] by Reiner Pope it turns out you can actually do this:

instance (f a b) = FMap f (HJust a) (HJust b) where
type f :$: (HJust a) = HJust (f :$: a)

A bit more awkward to write, but we're back to TFs not having any
expressivity problem in this department.

[1] 
http://www.reddit.com/r/haskell/comments/ut85i/a_few_typefamilies_nuggets/c4ygefh

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