Constants in Class definitions - could not deduce

Hello all, in my attempt to solve a Calendar related problem, I wanted to define Months and Weekdays such that I can increment a value. Unlike the "succ" Funktion in Enum my "inc" function shall circle endlessly. I came up with the following class (Ix a, Enum a) => Incrementable a where from :: a to :: a inc :: a -> a inc x = [from .. to] !! ((1 + index (from, to) x) `mod` rangeSize (from,to)) but GHC complains: /home/martin/projects/haskell/euler/p19.hs:39:65: Could not deduce (Ix a0) arising from a use of `rangeSize' from the context (Incrementable a) I suppose this is because GHC does not know that I want "to" and "from" to be taken from the same instance as x. If I replace the signature of "from" by "a -> a" and implement it by using a function which throws aways its argument, the types become clear and GHC no longer complains. Alternatively I can omit the implementation of "inc" in the class and leave that to the instances. I can easily fix the types in the instances, but this leads to some code duplication. I tried (from::a) to fix the type, but this had no effect. How is this done correctly?

Hi Martin, On 18/05/14 15:54, martin wrote:
Hello all,
in my attempt to solve a Calendar related problem, I wanted to define Months and Weekdays such that I can increment a value. Unlike the "succ" Funktion in Enum my "inc" function shall circle endlessly.
I came up with the following
class (Ix a, Enum a) => Incrementable a where from :: a to :: a inc :: a -> a inc x = [from .. to] !! ((1 + index (from, to) x) `mod` rangeSize (from,to))
but GHC complains:
/home/martin/projects/haskell/euler/p19.hs:39:65: Could not deduce (Ix a0) arising from a use of `rangeSize' from the context (Incrementable a)
I suppose this is because GHC does not know that I want "to" and "from" to be taken from the same instance as x. If I replace the signature of "from" by "a -> a" and implement it by using a function which throws aways its argument, the types become clear and GHC no longer complains.
Alternatively I can omit the implementation of "inc" in the class and leave that to the instances. I can easily fix the types in the instances, but this leads to some code duplication.
I tried (from::a) to fix the type, but this had no effect. How is this done correctly?
You could use `asTypeOf` (which is `const` with a specialized type): class (Ix a, Enum a) => Incrementable a where from :: a to :: a inc :: a -> a inc x = [f .. t] !! ((1 + index (f, t) x) `mod` rangeSize (f,t)) where f = from `asTypeOf` x ; t = to `asTypeOf` x hth, Claude -- http://mathr.co.uk

On Sun, May 18, 2014 at 5:14 PM, Claude Heiland-Allen
Hi Martin,
On 18/05/14 15:54, martin wrote:
Hello all,
in my attempt to solve a Calendar related problem, I wanted to define Months and Weekdays such that I can increment a value. Unlike the "succ" Funktion in Enum my "inc" function shall circle endlessly.
I came up with the following
class (Ix a, Enum a) => Incrementable a where from :: a to :: a inc :: a -> a inc x = [from .. to] !! ((1 + index (from, to) x) `mod` rangeSize (from,to))
but GHC complains:
/home/martin/projects/haskell/euler/p19.hs:39:65: Could not deduce (Ix a0) arising from a use of `rangeSize' from the context (Incrementable a)
I suppose this is because GHC does not know that I want "to" and "from" to be taken from the same instance as x. If I replace the signature of "from" by "a -> a" and implement it by using a function which throws aways its argument, the types become clear and GHC no longer complains.
Alternatively I can omit the implementation of "inc" in the class and leave that to the instances. I can easily fix the types in the instances, but this leads to some code duplication.
I tried (from::a) to fix the type, but this had no effect. How is this done correctly?
You could use `asTypeOf` (which is `const` with a specialized type):
class (Ix a, Enum a) => Incrementable a where from :: a to :: a inc :: a -> a inc x = [f .. t] !! ((1 + index (f, t) x) `mod` rangeSize (f,t)) where f = from `asTypeOf` x ; t = to `asTypeOf` x
Alternatively, you can turn on ScopedTypeVariables. That way, the 'a' variable from the class header is in scope in the code below it. Regards, Erik

Thanks, typeOf did the trick Am 05/18/2014 05:14 PM, schrieb Claude Heiland-Allen:
Hi Martin,
On 18/05/14 15:54, martin wrote:
Hello all,
in my attempt to solve a Calendar related problem, I wanted to define Months and Weekdays such that I can increment a value. Unlike the "succ" Funktion in Enum my "inc" function shall circle endlessly.
I came up with the following
class (Ix a, Enum a) => Incrementable a where from :: a to :: a inc :: a -> a inc x = [from .. to] !! ((1 + index (from, to) x) `mod` rangeSize (from,to))
but GHC complains:
/home/martin/projects/haskell/euler/p19.hs:39:65: Could not deduce (Ix a0) arising from a use of `rangeSize' from the context (Incrementable a)
I suppose this is because GHC does not know that I want "to" and "from" to be taken from the same instance as x. If I replace the signature of "from" by "a -> a" and implement it by using a function which throws aways its argument, the types become clear and GHC no longer complains.
Alternatively I can omit the implementation of "inc" in the class and leave that to the instances. I can easily fix the types in the instances, but this leads to some code duplication.
I tried (from::a) to fix the type, but this had no effect. How is this done correctly?
You could use `asTypeOf` (which is `const` with a specialized type):
class (Ix a, Enum a) => Incrementable a where from :: a to :: a inc :: a -> a inc x = [f .. t] !! ((1 + index (f, t) x) `mod` rangeSize (f,t)) where f = from `asTypeOf` x ; t = to `asTypeOf` x
hth,
Claude
participants (3)
-
Claude Heiland-Allen
-
Erik Hesselink
-
martin