You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The rumor is, it's unsafe. But it works to get nested Coercable applicative monoids. Here's the scoop: I want to randomly select an element out of a container. If the container is foldable this can be done using foldMap and monoids:
maybeChooseFirst:: (Foldablet) =>ta->Gen (Maybea)
maybeChooseFirst =fmap getFirst . getAp .foldMap (Ap.fmapFirst. pickOne)
wherepickOne::a->Gen (Maybea)
pickOne x = elements [Nothing, Just x]
This is done by mapping each element (x) in the structure and to QuickCheck's Gen applicative that selects either Nothing or Just x. The Ap and First are newtype wrappers
to make sure that one the FirstJust value is extracted and because we're folding and Gen isn't a monoid in its own right we have to piggy pack on Ap which is a monoid wrapper around applicatives.
As you can see pickOne is really the heart of this function but it's surrounded by a bunch of wrapping and unwrapping code to handle the newtypes. However, Newtype from the newtype package was built just for this. However, there's a slight problem. Ap f a unwraps to f a. This isn't an issue if we don't want to unwrap a. But, in our case, a ~ First b needs to unwrap to Maybe b. So we need a Newtype instance (the functor constraint to to ensure we can go up under the f and unwrap the a):
which the library doesn't provide. So I had to write my own:
newtypeAffa=Af{unAf::fa}deriving (Functor, Applicative)
instance (Applicativef, Monoidm) =>Semigroup (Affm) where
x <> y =Af$(<>)<$> (coerce x) <*> (coerce y)
instance (Applicativef, Monoidm) =>Monoid (Affm) wheremempty=Af$purememptyinstance (Functorf, Newtypeab) =>Newtype (Affa) (fb) where
pack =Af.fmap pack
unpack =fmap unpack . unAf
This requires UndecidableInstances extension. I'm not sure why but the compiler told me so and it's the boss...But! Using this I can coerce my heart's content to wrap and unwrap newtypes. As I think about it I wonder how useful lenses would have been here...
The text was updated successfully, but these errors were encountered:
A simple solution would be to get rid of Af and use coerce instead of the newtype package anywho. Instead I can use a custom newtype whos Semigroup instance handles the logic of randomly selecting between 2 randomly possibly selected values.
optparse-repline/test/Arbitrary/Repline.hs
Line 7 in 62e032f
The rumor is, it's unsafe. But it works to get nested Coercable applicative monoids. Here's the scoop: I want to randomly select an element out of a container. If the container is foldable this can be done using
foldMap
and monoids:This is done by mapping each element (
x
) in the structure and to QuickCheck'sGen
applicative that selects eitherNothing
orJust x
. TheAp
andFirst
are newtype wrappersto make sure that one the
First
Just
value is extracted and because we're folding andGen
isn't a monoid in its own right we have to piggy pack onAp
which is a monoid wrapper around applicatives.As you can see
pickOne
is really the heart of this function but it's surrounded by a bunch of wrapping and unwrapping code to handle the newtypes. However,Newtype
from thenewtype
package was built just for this. However, there's a slight problem.Ap f a
unwraps tof a
. This isn't an issue if we don't want to unwrapa
. But, in our case,a ~ First b
needs to unwrap toMaybe b
. So we need aNewtype
instance (the functor constraint to to ensure we can go up under thef
and unwrap thea
):which the library doesn't provide. So I had to write my own:
This requires
UndecidableInstances
extension. I'm not sure why but the compiler told me so and it's the boss...But! Using this I can coerce my heart's content to wrap and unwrap newtypes. As I think about it I wonder how useful lenses would have been here...The text was updated successfully, but these errors were encountered: