Explicitly import instances - haskell

How do I explicitly import typeclass instances? Also, how do I do this with a qualified import?
Currently, I'm doing
import Control.Monad.Error ()
to import the monad instance that I can use for (Either String). Previously, I used
import Control.Monad.Error
I'm not satisfied with either one, because the Monad instance is implicitly imported.

The inability to control imports of instances is one of the trade-offs the Haskell typeclass system makes. Here's an example in a hypothetical Haskell dialect where you can:
Foo.hs:
module Foo where
data Foo = FooA | FooB deriving (Eq, Ord)
Bar.hs:
module Bar (myMap) where
import Data.Map (Map)
import qualified Data.Map as Map
import Foo
myMap :: Map Foo Int
myMap = Map.singleton FooA 42
Baz.hs:
module Baz where
import Data.Map (Map)
import qualified Data.Map as Map
import Foo hiding (instance Ord Foo)
import Bar (myMap)
instance Ord Foo where
FooA > FooB = True
FooB > FooA = False
ouch :: Map Foo Int
ouch = Map.insert FooB 42 myMap
Yikes! The set myMap was created with the proper instance Ord Foo, but it's being combined with a map created with a different, contradictory instance.
Being able to do this would violate Haskell's open world assumption. Unfortunately, I don't know of a good, centralised resource for learning about it. This section of RWH might be helpful (I searched for "haskell open world assumption").

You can't. Instances are always implicitly exported and hence you can't explicitly import them. By the way, Either e's Monad instance is nowadays in Control.Monad.Instances.

Although the generally correct answer would be "no, you can't", I suggest this horrendous solution:
copy + paste
Take a look at the library source code for the desired module, and copy/paste the necessary data declarations, imports, and function definitions into your own code. Don't copy the instances you don't want.
Depending on the problem at hand, the ghc type system extensions OverlappingInstances or IncoherentInstances might be an alternate solution, though this probably won't solve any problems with the base libraries.

Related

How to organize definition with QuickCheck Arbitrary class in Haskell

I am learning to use QuickCheck and find it is a very powerful library. I wrote some toy program with stack, involving a few customized data type and defined all Arbitrary instances in one file in my first run like this and it worked well:
-- MyModule.hs
module MyModule
( A(..)
, B(..)
, ...
) where
data A = ...
data B = ... -- depends on type A
-- in test program
module TestMyModule where
import Test.QuickCheck
import MyModule
( A
, B
)
instance Arbitrary A where
arbitrary = ...
instance Arbitrary B where
arbitrary = ... -- depends on arbitrary for type A
prop_A :: A -> Bool
prop_A = undefined
prop_B :: B -> Bool
prop_B = undefined
main = do
quickCheck prop_A
quickCheck prop_B
This works quite well. However when I tried to separate files into two parts, one for A and one for B I ran into issues. I think this was really caused the test program split-up.
-- TestA program
import Test.QuickCheck
import MyModule (A)
instance Arbitrary A where
arbitrary = ...
...
-- TestB program
import Test.QuickCheck
import MyModule (A, B)
instance Arbitrary B where
arbitrary = ... -- code here depends on type A
I got errors like: No instance for (Arbitrary A) arising from a use of ‘quickCheck', which makes sense, because in TestB program, A is not an instance of Arbitrary. But how should I organize the files without putting Arbitrary instance in MyModule itself? I wanted to avoid putting test related definitions in the module.
Thank you in advance.
As Fyodor Soikin writes, you can package these Arbitray instances in a module that you put in your test library.
-- in test program
module MyTests.Arbs with
import Test.QuickCheck
import MyModule
-- Arbitrary instances go here...
-- Import MyTests.Arbs in your other test modules
The compiler ought to complain about orphan instances (it must have done so for the code in the OP as well), so you may want to consider wrapping those types in newtype definitions.
I use a naming scheme for that so that I'd typically have ValidA, InvalidB, AnyB, etc.

What is wrong with my data constructor import/use, when ghc suggestion is to add constructor to import list?

I have the following line of code where I'm trying to extract the internal raw type so I can work with it directly:
SDL.Internal.Types.Window (rawWindow) = window
My import looks like:
import qualified SDL.Internal.Types (Window)
The error I get is below; it seems I'm already doing what it suggests.
% /home/brandon/workspace/hico/src/Hico/Game.hs:273:5: error:
Not in scope: data constructor `SDL.Internal.Types.Window'
Perhaps you want to add `Window' to the import list
in the import of `SDL.Internal.Types' (src/Hico/Game.hs:34:1-48).
|
273 | SDL.Internal.Types.Window (rawWindow) = window
| ^^^^^^^^^^^^^^^^^^^^^^^^^
The content of the Types.hs file is very short, and doesn't seem to offer any clues to me:
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
module SDL.Internal.Types
( Joystick(..)
, Window(..)
, Renderer(..)
) where
import Data.Data (Data)
import Data.Typeable
import GHC.Generics (Generic)
import qualified SDL.Raw as Raw
newtype Joystick = Joystick { joystickPtr :: Raw.Joystick }
deriving (Data, Eq, Generic, Ord, Show, Typeable)
newtype Window = Window (Raw.Window)
deriving (Data, Eq, Generic, Ord, Show, Typeable)
-- | An SDL rendering device. This can be created with 'SDL.Video.createRenderer'.
newtype Renderer = Renderer Raw.Renderer
deriving (Data, Eq, Generic, Ord, Show, Typeable)
By writing
import qualified SDL.Internal.Types (Window)
you are importing only the type Window, and none of its constructors. To import a data type and some limited subset of its constructors, one writes (using Maybe as an example because I don't know SDL's types):
import Prelude (Maybe(Just))
This import would allow you to use Maybe in type annotations, and use the Just constructor to pattern-match or to create new values of type Maybe a, but you would not be able to use Nothing in either of those circumstances.
Note that the above would be a very unusual thing to do: normally you want either all of a type's constructors (so that you can build and consume any value of that type), or none of them (so that your functions can receive or return values of that type, constructed and consumed by other functions).
If you want all of a type's constructors, you can use the exact syntax used in the module export definition you listed: (..) means "all of the constructors of this type":
import qualified SDL.Internal.Types (Window(..))

haskell hide import of star-operator

I have:
import qualified GHC.Types as T hiding (Module, (*))
import GHC.TypeNats hiding ((*))
but when I try to define a (*)-operator, it fails:
{-# INLINE (*) #-}
infixl 7 *
(*) :: r -> r -> r
(*) = undefined
with
error:
Ambiguous occurrence ‘*’
It could refer to either ‘T.*’,
imported qualified from ‘GHC.Types’ at ...
or ‘*’,
imported from ‘GHC.TypeNats’ at ...
|
1277 | infixl 7 *
EDIT: the description is currently not reproducible. I will update the question as soon as I can.
Neither GHC.Types nor GHC.TypeNats have a (*) export. They both have a type (*) export. Usually, you can distinguish between term-level (*) and type-level (*) by context, but this is not true in export/import lists. Instead, term-level is taken as default, and you must explicitly say you want to hide the types.
import qualified GHC.Types as T hiding (Module, type (*))
import GHC.TypeNats hiding (type (*))
The reason Module remains unadorned is because the capitalization means it must be either a type, a constructor, or a pattern synonym. Constructors must occur inside grouping () next to their data types, and pattern synonyms must be set apart with pattern, so the Module above is taken to refer to the data type (hiding the data type also hides all of its constructors).
The reason you did not get an error when you tried to hide something that didn't exist is because hiding was designed so that, if the imported module ever stopped exporting something you hid, your module would not fail to compile. After all, the only reason you referenced that thing was to say that you weren't going to reference that thing.

How to Define Typeclass Synonyms

In an attempt to make a sane(r) alternative to Haskell's numeric type system, the devs of numeric-prelude slipped up and decided to name all of their type classes C. Aside from making the docs totally confusing, this means that I have to fully qualify all uses of the typeclasses:
import qualified Algebra.Additive (C)
import qualified Algebra.Ring (C)
...
newtype Foo a = Foo a
instance (Algebra.Additive.C a) => Algebra.Additive.C (Foo a) where ...
myadd :: (Algebra.Additive.C a) => a -> a -> a
myadd a b = ...
Also, since NumericPrelude has finer grained typeclasses, I usually have to import several different NumericPrelude modules. I can simplify this a little by defining top-level constraint synonyms:
{-# LANGUAGE ConstraintKinds #-}
module NPSynonyms (Additive) where
import qualified Algebra.Additive (C)
type Additive a = (Algebra.Additive.C a)
which allows me to make sane functions:
myadd :: (Additive a) => a -> a -> a
myadd a b = ...
However, when I need to define an instance, I still have to (also) import the original NumericPrelude class:
{-# LANGUAGE ConstraintKinds #-}
import NPSynonyms
import Algebra.Additive (C)
newtype Foo a = Foo a
instance (Additive a) => Algebra.Additive.C (Foo a) where ...
So instead of making Additive a type synonym with kind Constraint, what I'd really like is to define a typeclass synonym for the typeclass Algebra.Additive.C. Is there any way to do this in GHC 7.8, or is there any sane alternative?
you have to fully qualify
No, not fully qualify. Consider:
import qualified Algebra.Additive as Add
myadd :: Add.C a => a -> a -> a
That looks fairly readable to me.
EDIT:
Also consider making a superclass and treating that as an alias:
class (Add.C a, Ring.C a) => Num a where
instance Num Int
instance Num Word

Is it possible to construct a new record using Lenses?

If I have a record type with lenses, is it possible to construct a new record without using the underlying record accessors?
{-# LANGUAGE TemplateHaskell #-}
import Control.Lens
import Control.Lens.TH
data Foo = Foo { _s :: String
, _b :: Bool
} deriving (Show, Eq)
makeLenses ''Foo
I could make Foo an instance of Data.Default and then modifiy def with lenses, but not all record types will have sensible defaults. Does Control.Lens have its own way to do it?
No, there is currently no way to do that. You'll have to use something like Foo{} as default or not use lens for record construction. However, there is already an issue in lens covering this.

Resources