Balazs
Balazs

Reputation: 83

How to import just specific instances in haskell

I'm facing the following problem: I have multiple instances of a type class defined in a module but don't want to export all of them. How can I do that?

module SomeModule
  ( calculate
  )
where

class Something a where
  calculate :: a -> Int

instance Something Double where
  calculate x = calculate $ roundToInt x

instance Something Int where
  calculate x = doSomething x

roundToInt :: Double -> Int
roundToInt = round

doSomething :: Int -> Int
doSomething _ = 42

In this (simplified) example I have two instances of the type class Something which depend on each other, but I just would like to export the instance for Doubles and not for Ints. But in my example, both instances get exported implicitly. Is there a way around it?

Upvotes: 3

Views: 333

Answers (1)

Daniel Wagner
Daniel Wagner

Reputation: 152682

You can make the instances you want to hide be on a newtype that isn't exported.

module SomeModule (calculate) where

newtype NotInt = NotInt Int

class Something a where calculate :: a -> Int
instance Something Double where calculate x = calculate (NotInt (round x))
instance Something NotInt where calculate _ = 42

If there are many instances you do not want to export, a parameterized newtype might be less boilerplate.

{-# LANGUAGE FlexibleInstances #-}
module SomeModule (calculate) where

newtype Hidden a = Hidden a

class Something a where calculate :: a -> Int
instance Something Double where calculate x = calculate (Hidden (round x :: Int))
instance Something (Hidden Int) where calculate _ = 42

Another option is not to define the instance in the first place, and simply use a different name than the class's method name for the implementation of the other method you care about.

module SomeModule (calculate) where

class Something a where calculate :: a -> Int
instance Something Double where calculate x = calculateInt (round x)

calculateInt :: Int -> Int
calculateInt _ = 42

Upvotes: 6

Related Questions