-
Notifications
You must be signed in to change notification settings - Fork 29
NFData1 helper #8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Note that in the next version of class NFData1 f where
rnfWith :: (a -> ()) -> f a -> ()
rnf1 :: (NFData1 f, NFData a) => f a -> ()
rnf1 = rnfWith rnf
instance NFData1 [] where
rnfWith _ [] = ()
rnfWith rw (x:xs) = rw x `seq` rnfWith rw xs
instance (NFData1 f) => NFData1 (NonEmpty f) where
rnfWith rw (NonEmpty x xs) = rnf (rw x, rnfWith rw xs)
instance (NFData1 f, NFData a) => NFData (NonEmpty f a) where
rnf = rnf1 Functionally, |
I am not very sympathetic to the Haskell'98 motivation. For example, if you look at the evolution of Typeable, we have moved away from Typeable/Typeable1/Typeable2 using kind polymorphism. In the requester's case, FlexibleInstances works fine to support the instances he wants to write. |
Keep in mind that there is another important use-case for higher-kinded class analogues: handling polymorphic recursion. Using an example from http://flint.cs.yale.edu/trifonov/papers/sqcc.pdf: newtype Two f a = Two (f (f a))
data Sq f a = M a (f a) | E (Sq (Two f) a) One can create an instance NFData (f (f a)) => NFData (Two f a) where
rnf (Two t) = rnf t However, if we try to define an instance (NFData a, NFData (f a)) => NFData (Sq f a) where
rnf (M a f) = rnf (a, f)
rnf (E sq) = rnf sq If we try to typecheck this, GHC will complain that an With class NFData1 f where
rnfWith :: (a -> ()) -> f a -> ()
instance NFData1 f => NFData1 (Two f) where
rnfWith r (Two t) = rnfWith (rnfWith r) t
instance NFData1 f => NFData1 (Sq f) where
rnfWith r (M a f) = rnf (r a, rnfWith r f)
rnfWith r (E sq) = rnfWith r sq By the way, this reveals the power of the |
Technically, anything you can do with If someone can come up with a way to make |
@dolio I doubt that
E.g. instance (Functor f, Eq1 f, Eq1 g) => Eq1 (Compose f g) where eq1 = (==) when in instance (Eq1 f, Eq1 g) => Eq1 (Compose f g) where
liftEq eq (Compose x) (Compose y) = liftEq (liftEq eq) x y Same would hold for class NFData1' f where
rnf1 :: NFData a => f a -> ()
{-
instance NFData1' f => NFData1' (Two f) where
rnf1 (Two t) = rnf1 t
-- Could not deduce (NFData (f a)) arising from a use of ‘rnf1’
-- from the context (NFData1' f)
-}
data X f a = X { getX :: f a }
instance Functor f => Functor (X f) where
fmap f (X x) = X (fmap f x)
instance NFData1' f => NFData1' (X f) where
rnf1 (X x) = rnf1 x
instance (NFData1' f, NFData a) => NFData (X f a) where
rnf = rnf1
instance (NFData1' f, Functor f) => NFData1' (Two f) where
rnf1 (Two t) = rnf1 (fmap X t) |
@dolio also in GHC-8.0 you can do not so messy polymorphic classes, because of injective type families and |
Yes, I think it's true that you need some extra conditions to use the old style, because fooWith contains some evidence that the type in question is covariant (or more precisely perhaps, foldable). I guess that polykinded NFData example isn't too terrible. :) I'm not sure I could support it going into the library, though. It seems like it'd be unpleasant to actually use without the wrappers. But maybe that's not a big deal; I don't know. |
ekmett/bound#36 needs for some kind of |
quoting http://permalink.gmane.org/gmane.comp.lang.haskell.libraries/24907, Henning writes
The text was updated successfully, but these errors were encountered: