Monad instances and type synonyms

I am playing around with some trivial code (for learning purposes) I wanted to take code: -------- -- SaleVariables a concrete type defined early -- `Adjustment' represents adjustment in a price calculation -- Allows functions of type (a -> Adjustment a) to be composed -- with an appropriate composition function type Adjustment a = SaleVariables -> a -------- And put it into code: -------- instance Monad Adjustment where (>>=) = ... return = ... -------- If I try this, I get code: -------- Type synonym `Adjustment' should have 1 argument, but has been given none In the instance declaration for `Monad Adjustment' -------- But if I give an argument, then it doesn't compile either (it becomes a "*" kind). And I didn't want to make the type with a regular "data" declaration either, because then I have to give it a constructor, which doesn't fit with what I want the type to do. -- frigidcode.com

On Sat, Apr 13, 2013 at 05:03:57PM -0800, Christopher Howard wrote:
I am playing around with some trivial code (for learning purposes) I wanted to take
code: -------- -- SaleVariables a concrete type defined early
-- `Adjustment' represents adjustment in a price calculation -- Allows functions of type (a -> Adjustment a) to be composed -- with an appropriate composition function type Adjustment a = SaleVariables -> a --------
And put it into
code: -------- instance Monad Adjustment where
(>>=) = ... return = ... --------
If I try this, I get
code: -------- Type synonym `Adjustment' should have 1 argument, but has been given none In the instance declaration for `Monad Adjustment' --------
But if I give an argument, then it doesn't compile either (it becomes a "*" kind). And I didn't want to make the type with a regular "data" declaration either, because then I have to give it a constructor, which doesn't fit with what I want the type to do.
Sorry, what you're trying to do is simply not possible. Type synonyms must always be fully applied. So if you want to make Adjustment an instance of Monad then you have to make it a newtype. However... Adjustment already *is* an instance of Monad! (In particular ((->) e) is an instance for any type e.) So there's no need for you to redeclare an instance yourself. These days I think you just have to import Control.Monad to bring the instance in scope. -Brent

On 04/14/2013 04:09 AM, Brent Yorgey wrote:
On Sat, Apr 13, 2013 at 05:03:57PM -0800, Christopher Howard wrote:
Sorry, what you're trying to do is simply not possible. Type synonyms must always be fully applied. So if you want to make Adjustment an instance of Monad then you have to make it a newtype.
However... Adjustment already *is* an instance of Monad! (In particular ((->) e) is an instance for any type e.) So there's no need for you to redeclare an instance yourself. These days I think you just have to import Control.Monad to bring the instance in scope.
-Brent
Thank you everyone for your patience. I believe what you say about it already being an instance of Monad, but I don't seem to have convinced the compiler: code: -------- import Control.Monad -- ...snip... type Adjustment = (->) SaleVariables addTax :: Cash -> Adjustment Cash addTax cash = \v -> cash * (1 + salesTax v) -- obviously silly to add taxes twice, but work with me here testrun = addTax 10.00 >>= \c -> addTax c -------- gives me code: -------- No instance for (Monad ((->) SaleVariables)) arising from a use of `>>=' Possible fix: add an instance declaration for (Monad ((->) SaleVariables)) In the expression: addTax 10.00 >>= \ c -> addTax c In an equation for `testrun': testrun = addTax 10.00 >>= \ c -> addTax c -------- -- frigidcode.com

On Mon, Apr 15, 2013 at 09:51:11PM -0800, Christopher Howard wrote:
On 04/14/2013 04:09 AM, Brent Yorgey wrote:
On Sat, Apr 13, 2013 at 05:03:57PM -0800, Christopher Howard wrote:
Sorry, what you're trying to do is simply not possible. Type synonyms must always be fully applied. So if you want to make Adjustment an instance of Monad then you have to make it a newtype.
However... Adjustment already *is* an instance of Monad! (In particular ((->) e) is an instance for any type e.) So there's no need for you to redeclare an instance yourself. These days I think you just have to import Control.Monad to bring the instance in scope.
-Brent
Thank you everyone for your patience. I believe what you say about it already being an instance of Monad, but I don't seem to have convinced the compiler:
What version of GHC do you have? Try 'import Control.Monad.Instances' in place of 'Control.Monad'. The instances have moved but I don't remember when. -Brent

On 04/16/2013 05:57 AM, Brent Yorgey wrote:
On Mon, Apr 15, 2013 at 09:51:11PM -0800, Christopher Howard wrote:
What version of GHC do you have? Try 'import Control.Monad.Instances' in place of 'Control.Monad'. The instances have moved but I don't remember when.
-Brent
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
On 04/16/2013 05:57 AM, Brent Yorgey wrote:> On Mon, Apr 15, 2013 at 09:51:11PM -0800, Christopher Howard wrote:
What version of GHC do you have? Try 'import Control.Monad.Instances' in place of 'Control.Monad'. The instances have moved but I don't remember when.
Control.Monad.Instances worked, thanks. I am running GHC 7.4.1. -- frigidcode.com
participants (2)
-
Brent Yorgey
-
Christopher Howard