Automatically deriving PathPiece - haskell

In my Yesod web-application I have following data type:
data SensorType = TemperatureSensor | HumiditySensor deriving (Eq, Show, Read, PathPiece, PersistField)
I enable GeneralizedNewtypeDeriving
The answer about automatically deriving PathPiece:
What typeclasses need to be defined for a Yesod path?
But I get ghc-error:
Can't make a derived instance of `PathPiece SensorType
`PathPiece' is not a derivable class
Is it possible automatically derive PathPiece? What I do wrong?
For PersistField exists derivePersistField. What about PathPiece?

GeneralizedNewtypeDeriving, as its name implies, is only useful for deriving instances for newtypes. It works by lifting instances of the underlying type over the newtype wrapper.
Your type is not a newtype so there is no PathPiece instance to lift.

It doesn't look like that's possible, based on the path-pieces package not doing anything like that or any code I can find on Github. I would implement the PathPiece typeclass like this (using tshow and readMay from classy prelude):
instance PathPiece SensorType where
toPathPiece = tshow
fromPathPiece = readMay

Related

Derived instance in Haskell

I would like to use derived instance like this:
data Test3D = forall a. (Show a, Eq a, Typeable a, Generic a)
=> Test3D { testDt :: String
, testPrm :: a
}
deriving (Show, Eq, Typeable, Generic)
instance Binary (Test3D)
$(deriveJSON defaultOptions ''Test3D)
But I received from GHC:
• Can't make a derived instance of ‘Show Test3D’:
Constructor ‘Test3D’ has existentials or constraints in its type
Possible fix: use a standalone deriving declaration instead
• In the data declaration for ‘Test3D’
This way is very convenient for my project. I can not find the solution.
Is any way of using derived instance for such data?
Is any way of using derived instance for such data?
Yes. Do what GHC suggested, make a standalone deriving clause:
{-# LANGUAGE StandaloneDeriving, ExistentialQuantification #-}
data Test3D = forall a. (Show a)
=> Test3D { testDt :: String
, testPrm :: a
}
deriving instance Show Test3D
What you cannot do is derive an Eq instance, because different values may actually contain different types and it's only possible to compare these with a dynamic-cast hack through Typeable.

On inferring fmap for ADTs

Suppose that two new types are defined like this
type MyProductType a = (FType1 a, FType2 a)
type MyCoproductType a = Either (FType1 a) (FType2 a)
...and that FType1 and Ftype2 are both instances of Functor.
If one now were to declare MyProductType and MyCoproductType as instances of Functor, would the compiler require explicit definitions for their respective fmap's, or can it infer these definitions from the previous ones?
Also, is the answer to this question implementation-dependent, or does it follow from the Haskell spec?
By way of background, this question was motivated by trying to make sense of a remark in something I'm reading. The author first defines
type Writer a = (a, String)
...and later writes (my emphasis)
...the Writer type constructor is functorial in a. We don't even have to implement fmap for it, because it's just a simple product type.
The emphasized text is the remark I'm trying to make sense of. I thought it meant that Haskell could infer fmap's for any ADT based on functorial types, and, in particular, it could infer the fmap for a "simple product type" like Writer, but now I think this interpretation is not right (at least if I'm reading Ørjan Johansen's answer correctly).
As for what the author meant by that sentence, now I really have no clue. Maybe all he meant is that it's not worth the trouble to re-define Writer in such a way that its functoriality can be made explicit, since it's such a "simple ... type". (Grasping at straws here.)
First, you cannot generally define new instances for type synonyms, especially not partially applied ones as you would need in your case. I think you meant to define a newtype or data instead:
newtype MyProductType a = MP (FType1 a, FType2 a)
newtype MyCoproductType a = MC (Either (FType1 a) (FType2 a))
Standard Haskell says nothing about deriving Functor automatically at all, that is only possible with GHC's DeriveFunctor extension. (Or sometimes GeneralizedNewtypeDeriving, but that doesn't apply in your examples because you're not using a just as the last argument inside the constructor.)
So let's try that:
{-# LANGUAGE DeriveFunctor #-}
data FType1 a = FType1 a deriving Functor
data FType2 a = FType2 a deriving Functor
newtype MyProductType a = MP (FType1 a, FType2 a) deriving Functor
newtype MyCoproductType a = MC (Either (FType1 a) (FType2 a)) deriving Functor
We get the error message:
Test.hs:6:76:
Can't make a derived instance of ‘Functor MyCoproductType’:
Constructor ‘MC’ must use the type variable only as the last argument of a data type
In the newtype declaration for ‘MyCoproductType’
It turns out that GHC can derive the first three, but not the last one. I believe the third one only works because tuples are special cased. Either doesn't work though, because GHC doesn't keep any special knowledge about how Either treats its first argument. It's nominally a mathematical functor in that argument, but not a Haskell Functor.
Note that GHC is smarter about using variables only as last argument of types known to be Functors. The following works fine:
newtype MyWrappedType a = MW (Either (FType1 Int) (FType2 (Maybe a))) deriving Functor
So to sum up: It depends, GHC has an extension for this but it's not always smart enough to do what you want.

deriving clause with arbitrary "Constraint aliases"?

For example, this declaration with deriving:
{-# LANGUAGE DeriveDataTypeable, ConstraintKinds #-}
import Data.Data (Data)
import Data.Typeable (Typeable)
type Constraints a = (Show a, Eq a, Ord a, Data a, Typeable a)
data A = A deriving (Constraints)
errors with:
Illegal deriving item ‘Constraints’
Which makes sense given http://downloads.haskell.org/~ghc/7.8.3/docs/html/users_guide/deriving.html
I write deriving (Show, Eq, Ord, Data, Typeable) for most of my types. It might be nice to export standard "constraint aliases", i.e. any type of kind * -> Constraint. Given, of course, that the constraints in the constraint tuple are all the right arity, have an empty "minimal complete definition", etc.
Is there any proposal for this? How hard would it be? Are there alternatives?
There is no proposal for this. It wouldn't be too hard, but I suspect it wouldn't get a lot of traction. Not only could you use template haskell to generate standalone deriving declarations as a comment suggests, but you could macro-expand to your desired clause using CPP if you really want.

Stackoverflow exception when comparing two dynamic types

I have defined a data type Loc which can accept Dynamics in the constructor. Moreover I need to compare Loc datatypes using == operator. So I came up with something like this:
data Loc = UnknownLoc | DynamicLoc Dynamic deriving (Eq,Show)
instance Eq Dynamic
data DynamicLocation = Loc_1 | Loc_2 deriving (Eq,Show)
instance Typeable DynamicLocation
But when attempting to run the following line I get stackoverflow exception.
DynamicLoc (toDyn Loc_1) == DynamicLoc (toDyn Loc_1)
any idea?
Please, read your compiler warnings :) You haven't provided a definition for the Typeable typeclass's typeOf method for DynamicLocation, and toDyn calls typeOf. So this definitely shouldn't work -- if you try just toDyn Loc_1, you'll get an exception.
But why an infinite loop? It's because you also haven't defined (==) for Dynamic, and (==) and (/=) are defined in terms of each other in GHC.Classes. GHC doesn't attempt to resolve such infinite recursion in default method declarations, so you unfortunately don't get a warning.
What to do? I suggest letting GHC derive the Typeable instance for you:
{-# LANGUAGE StandaloneDeriving, DeriveDataTypeable #-}
data DynamicLocation = Loc_1 | Loc_2 deriving (Eq,Show)
deriving instance Typeable DynamicLocation
or, more sensible:
{-# LANGUAGE DeriveDataTypeable #-}
data DynamicLocation = Loc_1 | Loc_2 deriving (Eq,Show,Typeable)
However, as a commenter has already pointed out, it's not immediately clear how to define (==) for Dynamic, or if this is even possible.

How do I write, "if typeclass a, then a is also an instance of b by this definition."

I have a typeclass MyClass, and there is a function in it which produces a String. I want to use this to imply an instance of Show, so that I can pass types implementing MyClass to show. So far I have,
class MyClass a where
someFunc :: a -> a
myShow :: a -> String
instance MyClass a => Show a where
show a = myShow a
which gives the error Constraint is no smaller than the instance head. I also tried,
class MyClass a where
someFunc :: a -> a
myShow :: a -> String
instance Show (MyClass a) where
show a = myShow a
which gives the error, ClassMyClass' used as a type`.
How can I correctly express this relationship in Haskell?
Thanks.
I should add that I wish to follow this up with specific instances of MyClass that emit specific strings based on their type. For example,
data Foo = Foo
data Bar = Bar
instance MyClass Foo where
myShow a = "foo"
instance MyClass Bar where
myShow a = "bar"
main = do
print Foo
print Bar
I wish to vigorously disagree with the broken solutions posed thus far.
instance MyClass a => Show a where
show a = myShow a
Due to the way that instance resolution works, this is a very dangerous instance to have running around!
Instance resolution proceeds by effectively pattern matching on the right hand side of each instance's =>, completely without regard to what is on the left of the =>.
When none of those instances overlap, this is a beautiful thing. However, what you are saying here is "Here is a rule you should use for EVERY Show instance. When asked for a show instance for any type, you'll need an instance of MyClass, so go get that, and here is the implementation." -- once the compiler has committed to the choice of using your instance, (just by virtue of the fact that 'a' unifies with everything) it has no chance to fall back and use any other instances!
If you turn on {-# LANGUAGE OverlappingInstances, IncoherentInstances #-}, etc. to make it compile, you will get not-so-subtle failures when you go to write modules that import the module that provides this definition and need to use any other Show instance. Ultimately you'll be able to get this code to compile with enough extensions, but it sadly will not do what you think it should do!
If you think about it given:
instance MyClass a => Show a where
show = myShow
instance HisClass a => Show a where
show = hisShow
which should the compiler pick?
Your module may only define one of these, but end user code will import a bunch of modules, not just yours. Also, if another module defines
instance Show HisDataTypeThatHasNeverHeardOfMyClass
the compiler would be well within its rights to ignore his instance and try to use yours.
The right answer, sadly, is to do two things.
For each individual instance of MyClass you can define a corresponding instance of Show with the very mechanical definition
instance MyClass Foo where ...
instance Show Foo where
show = myShow
This is fairly unfortunate, but works well when there are only a few instances of MyClass under consideration.
When you have a large number of instances, the way to avoid code-duplication (for when the class is considerably more complicated than show) is to define.
newtype WrappedMyClass a = WrapMyClass { unwrapMyClass :: a }
instance MyClass a => Show (WrappedMyClass a) where
show (WrapMyClass a) = myShow a
This provides the newtype as a vehicle for instance dispatch. and then
instance Foo a => Show (WrappedFoo a) where ...
instance Bar a => Show (WrappedBar a) where ...
is unambiguous, because the type 'patterns' for WrappedFoo a and WrappedBar a are disjoint.
There are a number of examples of this idiom running around in the the base package.
In Control.Applicative there are definitions for WrappedMonad and WrappedArrow for this very reason.
Ideally you'd be able to say:
instance Monad t => Applicative t where
pure = return
(<*>) = ap
but effectively what this instance is saying is that every Applicative should be derived by first finding an instance for Monad, and then dispatching to it. So while it would have the intention of saying that every Monad is Applicative (by the way the implication-like => reads) what it actually says is that every Applicative is a Monad, because having an instance head 't' matches any type. In many ways, the syntax for 'instance' and 'class' definitions is backwards.
(Edit: leaving the body for posterity, but jump to the end for the real solution)
In the declaration instance MyClass a => Show a, let's examine the error "Constraint is no smaller than the instance head." The constraint is the type class constraint to the left of '=>', in this case MyClass a. The "instance head" is everything after the class you're writing an instance for, in this case a (to the right of Show). One of the type inference rules in GHC requires that the constraint have fewer constructors and variables than the head. This is part of what are called the 'Paterson Conditions'. These exist as a guarantee that type checking terminates.
In this case, the constraint is exactly the same as the head, i.e. a, so it fails this test. You can remove the Paterson condition checks by enabling UndecidableInstances, most likely with the {-# LANGUAGE UndecidableInstances #-} pragma.
In this case, you're essentially using your class MyClass as a typeclass synonym for the Show class. Creating class synonyms like this is one of the canonical uses for the UndecidableInstances extension, so you can safely use it here.
'Undecidable' means that GHC can't prove typechecking will terminate. Although it sounds dangerous, the worst that can happen from enabling UndecidableInstances is that the compiler will loop, eventually terminating after exhausting the stack. If it compiles, then obviously typechecking terminated, so there are no problems. The dangerous extension is IncoherentInstances, which is as bad as it sounds.
Edit: another problem made possible by this approach arises from this situation:
instance MyClass a => Show a where
data MyFoo = MyFoo ... deriving (Show)
instance MyClass MyFoo where
Now there are two instances of Show for MyFoo, the one from the deriving clause and the one for MyClass instances. The compiler can't decide which to use, so it will bail out with an error message. If you're trying to make MyClass instances of types you don't control that already have Show instances, you'll have to use newtypes to hide the already-existing Show instances. Even types without MyClass instances will still conflict because the definition instance MyClass => Show a because the definition actually provides an implementation for all possible a (the context check comes in later; its not involved with instance selection)
So that's the error message and how UndecidableInstances makes it go away. Unfortunately it's a lot of trouble to use in actual code, for reasons Edward Kmett explains. The original impetus was to avoid specifying a Show constraint when there's already a MyClass constraint. Given that, what I would do is just use myShow from MyClass instead of show. You won't need the Show constraint at all.
I think it would be better to do it the other way around:
class Show a => MyClass a where
someFunc :: a -> a
myShow :: MyClass a => a -> String
myShow = show
You can compile it, but not with Haskell 98, You have to enable some language extensions :
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
-- at the top of your file
Flexible instances is there to allow context in instance declaration. I don't really know the meaning of UndecidableInstances, but I would avoid as much as I can.
As Ed Kmett pointed out, this is not possible at all for your case. If however you have access to the class you want to provide a default instance for, you can reduce the boilerplate to a minimum with a default implementation and constrain the input type with the default signature you need:
{-# LANGUAGE DefaultSignatures #-}
class MyClass a where
someFunc :: a -> Int
class MyShow a where
myShow :: a -> String
default myShow :: MyClass a => a -> String
myShow = show . someFunc
instance MyClass Int where
someFunc i = i
instance MyShow Int
main = putStrLn (myShow 5)
Note that the only real boilerplate (well, apart from the whole example) reduced to instance MyShow Int.
See aesons ToJSON for a more realistic example.
You may find some interesting answers in a related SO question: Linking/Combining Type Classes in Haskell

Resources