[GHC] #13876: Check 'pure' method of 'Applicative (WrappedMonad m)'

#13876: Check 'pure' method of 'Applicative (WrappedMonad m)' -------------------------------------+------------------------------------- Reporter: Iceland_jack | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.0.1 Keywords: | Operating System: Unknown/Multiple Architecture: | Type of failure: None/Unknown Unknown/Multiple | Test Case: | Blocked By: Blocking: | Related Tickets: Differential Rev(s): | Wiki Page: -------------------------------------+------------------------------------- Should {{{#!hs instance Monad m => Applicative (WrappedMonad m) where pure = WrapMonad . pure WrapMonad f <*> WrapMonad v = WrapMonad (f `ap` v) }}} not use `return`? {{{#!hs instance Monad m => Applicative (WrappedMonad m) where pure = WrapMonad . return WrapMonad f <*> WrapMonad v = WrapMonad (f `ap` v) }}} -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13876 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#13876: Check 'pure' method of 'Applicative (WrappedMonad m)' -------------------------------------+------------------------------------- Reporter: Iceland_jack | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.0.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Changes (by bgamari): * cc: hvr, ekmett, core-libraries-committee@… (added) Comment: Perhaps. However, given that `pure` and `return` shouldn't differ, and that the "`Monad` of no `return`" was seriously considered, it's not clear to me whether it matters enough to change it. The moment `pure /= return` you have bigger problems. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13876#comment:1 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#13876: Check 'pure' method of 'Applicative (WrappedMonad m)' -------------------------------------+------------------------------------- Reporter: Iceland_jack | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.0.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by RyanGlScott): Indeed, this was changed from `pure = WrapMonad. return` to `pure = WrapMonad . pure` in e737a5126dcfdd0610587d2ec16bea6481cf2a42 (`base: MRP- refactoring of AMP instances`), so perhaps hvr should chime in here. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13876#comment:2 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

Perhaps. However, given that `pure` and `return` shouldn't differ, and
#13876: Check 'pure' method of 'Applicative (WrappedMonad m)' -------------------------------------+------------------------------------- Reporter: Iceland_jack | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.0.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by Iceland_jack): Replying to [comment:1 bgamari]: that the "`Monad` of no `return`" was seriously considered, it's not clear to me whether it matters enough to change it. The moment `pure /= return` you have bigger problems. It matters in the following code: {{{#!hs {-# Language TypeApplications, ScopedTypeVariables, InstanceSigs, RankNTypes, DeriveFunctor, GeneralizedNewtypeDeriving #-} import Control.Monad import Data.Coerce -- As in Control.Applicative newtype WrappedMonad m a = WrapMonad { unwrapMonad :: m a } deriving (Monad) instance Monad m => Functor (WrappedMonad m) where fmap :: (a -> b) -> (WrappedMonad m a -> WrappedMonad m b) fmap f (WrapMonad v) = WrapMonad (liftM f v) instance Monad m => Applicative (WrappedMonad m) where pure :: a -> WrappedMonad m a pure = WrapMonad . pure (<*>) :: WrappedMonad m (a -> b) -> WrappedMonad m a -> WrappedMonad m b WrapMonad f <*> WrapMonad v = WrapMonad (f `ap` v) -- Definition defining `Applicative' roundtripping through `WrappedMonad' data V3 a = V3 a a a deriving (Functor, Show) instance Applicative V3 where pure :: forall a. a -> V3 a pure = coerce (pure @(WrappedMonad V3) @a) (<*>) :: forall a b. V3 (a -> b) -> V3 a -> V3 b (<*>) = coerce ((<*>) @(WrappedMonad V3) @a @b) instance Monad V3 where return :: a -> V3 a return a = V3 a a a (>>=) :: V3 a -> (a -> V3 b) -> V3 b V3 a b c >>= f = V3 a' b' c' where V3 a' _ _ = f a V3 _ b' _ = f b V3 _ _ c' = f c }}} If we try to run `pure @V3 'a'` it loops.. but replace `pure = WrapMonad . pure` by `pure = WrapMonad . return` and it works as expected. but comment `Control.Applicative` out and un-comment the definition of `WrapMonad` (th -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13876#comment:3 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#13876: Check 'pure' method of 'Applicative (WrappedMonad m)' -------------------------------------+------------------------------------- Reporter: Iceland_jack | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.0.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by Iceland_jack): To explain: this is not about defining `pure` / `return` differently but rather defining `pure @V3` in terms of `pure @(WrappedMonad V3)` to make use of the methods of `Monad` to define the methods of `Applicative` {{{#!hs pure @V3 @a = coerce (pure @(WrappedMonad V3) @a) = coerce (WrapMonad . pure @V3 @a) = pure @V3 @a }}} With my suggestion this works {{{#!hs pure @V3 @a = coerce (pure @(WrappedMonad V3) @a) = coerce (WrapMonad . return @V3 @a) = return @V3 @a }}} If MRP goes through then I would need a `newtype` wrapped with a `Pointed` & `Monad` constraint to define `Applicative`. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13876#comment:4 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#13876: Check 'pure' method of 'Applicative (WrappedMonad m)' -------------------------------------+------------------------------------- Reporter: Iceland_jack | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.0.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by RyanGlScott): I think I agree with bgamari here. Although we haven't removed `return` from `Monad` entirely, we've already taken the important step of refactoring just about all of `base` to define things first and foremost in terms of `pure`, and defining `return = pure` elsewhere. At this point, making another change to the semantics of `WrapMonad`'s `return` instance just for this use case feels pointless in the long run since, as others have noted, `return` really should work the same as `pure` from here on out in anticipation of `return`'s eventual removal from the `Monad` class. As for a solution to your problem, I'd suggest your idea of having another wrapper `newtype` that uses `Pointed` and `Monad` to retrofit `Applicative` instances. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13876#comment:5 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#13876: Check 'pure' method of 'Applicative (WrappedMonad m)' -------------------------------------+------------------------------------- Reporter: Iceland_jack | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.0.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by Iceland_jack): That's fine for [https://www.reddit.com/r/haskell/comments/6ksr76/rfc_part_1_deriving_instanc... what I'm doing], but what is the newtype used for now? -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13876#comment:6 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#13876: Check 'pure' method of 'Applicative (WrappedMonad m)' -------------------------------------+------------------------------------- Reporter: Iceland_jack | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.0.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by RyanGlScott): It's useful since you often want to define `(<*>)` in terms of `(>>=)`. I'm putting this in a distinct category of retrofitted things from defining `return` from `pure`, since the latter is completely trivial (`return = pure`), whereas the former requires a tad more work. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13876#comment:7 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#13876: Check 'pure' method of 'Applicative (WrappedMonad m)' -------------------------------------+------------------------------------- Reporter: Iceland_jack | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.0.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: #14200 | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Changes (by RyanGlScott): * related: => #14200 Comment: Note that there is talk of deprecating `WrappedMonad` entirely, which may make this ticket moot. See #14200. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13876#comment:8 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#13876: Check 'pure' method of 'Applicative (WrappedMonad m)' -------------------------------------+------------------------------------- Reporter: Iceland_jack | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.0.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: #14200 | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Changes (by dfeuer): * cc: dfeuer (added) Comment: In my opinion, there are two reasonable ways forward: 1. Adopt `Monad` of no `return`, and deprecate and remove `WrappedMonad` altogether. 2. Change the definition of `pure` for `WrappedMonad` back to using `return`, which will make it usable, among other things, for defining `Functor` and `Applicative` instances using `DerivingVia`. 1 may happen (I personally hope so), but probably not this year. I don't personally see any serious downside to proceeding with 2 for the time being. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13876#comment:9 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#13876: Check 'pure' method of 'Applicative (WrappedMonad m)' -------------------------------------+------------------------------------- Reporter: Iceland_jack | Owner: (none) Type: bug | Status: patch Priority: normal | Milestone: Component: Compiler | Version: 8.0.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: #14200 | Differential Rev(s): Phab:D4638 Wiki Page: | -------------------------------------+------------------------------------- Changes (by dfeuer): * status: new => patch * differential: => Phab:D4638 -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13876#comment:10 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler
participants (1)
-
GHC