Haskell "import qualified" and "Not in scope: data constructor" - haskell

I have an import like this:
import qualified Bioinformatics.DNA as DNA
from an other file looking like this:
data DNA = A | C | G | T
deriving (Eq, Ord, Show)
And in this function in the module RNA where:
module Bioinformatics.RNA
( RNA
, fromDna
) where
import qualified Bioinformatics.DNA as DNA
data RNA = A | C | G | U
deriving (Eq, Ord, Show)
fromDna :: DNA.DNA -> RNA
fromDna DNA.A = A
fromDna DNA.C = C
fromDna DNA.G = G
fromDna DNA.T = U
I receive errors:
/home/thibaud/code/bioinformatics/src/Bioinformatics/RNA.hs:46:9:
Not in scope: data constructor ‘DNA.A’
/home/thibaud/code/bioinformatics/src/Bioinformatics/RNA.hs:47:9:
Not in scope: data constructor ‘DNA.C’
/home/thibaud/code/bioinformatics/src/Bioinformatics/RNA.hs:48:9:
Not in scope: data constructor ‘DNA.G’
/home/thibaud/code/bioinformatics/src/Bioinformatics/RNA.hs:49:9:
Not in scope: data constructor ‘DNA.T’
Do you have an idea why?
Thanks

Use (..) to import all the constructors of a data type.
import qualified Bioinformatics.DNA as DNA (DNA(..), A, C, G, T)
Code Breakdown
EDIT: Let's break down your code a little since its not quite idiomatic.
import qualified Bioinformatics.DNA as DNA (DNA(..), A, C, G, T)
That's already an odd one. Typically people import things qualified or selectively, not both. Try just:
import qualified Bioinfomatics.DNA as DNA
So lets keep the quantification and drop the explicit list of symbols.
Now for the use, you have:
fromDna :: DNA.DNA -> RNA
fromDna DNA.A = A
fromDna DNA.C = C
fromDna DNA.G = G
fromDna DNA.T = U
The claim that this function converts from DNA to RNA. Note your questino never presented an RNA type or constructors - are those in your code somewhere? The remaining error from the code you posted is with respect to RNA, consider something like:
import qualified Bioinformatics.RNA as RNA
fromDna :: DNA.DNA -> RNA.RNA
fromDna DNA.A = RNA.A
fromDna DNA.C = RNA.C
fromDna DNA.G = RNA.G
fromDna DNA.T = RNA.U

Let's imagine we need a Geometry.Shape module for operations on a shapes. First, we'll make a folder called Geometry. Mind the capital G. In it, we'll place the Shape.hs file. Here's what the file will contain:
module Geometry.Shape
( Shape(Circle,Rectangle)
, Point
) where
data Point = Point Float Float deriving (Show)
data Shape = Circle Point Float | Rectangle Point Point deriving (Show)
Notice that when defining a point, we used the same name for the data type and the value constructor.
So let's assume that we need the Geometry module for various geometric calculations. We will create the Geometry.hs file and place it at the same level as the Geometry directory:
module Geometry (area) where
import qualified Geometry.Shape as Shape
area :: Shape.Shape -> Float
area (Shape.Circle _ r) = pi * r ^ 2
area (Shape.Rectangle (Shape.Point x1 y1) (Shape.Point x2 y2)) =
(abs $ x2 - x1) * (abs $ y2 - y1)
The file structure should now look like this:
.
├── Geometry
│   └── Shape.hs
└── Geometry.hs
Well, let's check our area function. First we need to open GHCi in the same directory as the Geometry.hs file.
$ ghci
GHCi, version 7.10.3: http://www.haskell.org/ghc/ :? for help
Prelude>
Then let's load Geometry module:
Prelude> :l Geometry.hs
[1 of 2] Compiling Geometry.Shape ( Geometry/Shape.hs, interpreted )
[2 of 2] Compiling Geometry ( Geometry.hs, interpreted )
Geometry.hs:7:24: Not in scope: data constructor ‘Shape.Point’
Geometry.hs:7:44: Not in scope: data constructor ‘Shape.Point’
Failed, modules loaded: Geometry.Shape.
Oops! Something went wrong. But wait! Look again at the error message:
Not in scope: data constructor ‘Shape.Point’
Well, simply speaking, it means that the type constructor is not in the reachable scope. So let's fix it by changing the Shape.hs file as follows:
module Geometry.Shape
( Shape(Circle,Rectangle)
, Point(..)
) where
Notice we changed Point to Point(..). Reload module as follows:
Prelude> :r
[1 of 2] Compiling Geometry.Shape ( Geometry/Shape.hs, interpreted )
[2 of 2] Compiling Geometry ( Geometry.hs, interpreted )
Ok, modules loaded: Geometry, Geometry.Shape.
and test it:
Prelude> area (Shape.Circle (Shape.Point 0 0) 24)
1809.5574
Yay, it works! I want to draw your attention to the fact that we used (..) to import all the constructors of the Point data type. It's the same as writing Point (Point). Similarly, we could use Shape(..) instead of Shape(Circle,Rectangle). For more see: https://www.haskell.org/tutorial/modules.html
Not exporting the value constructors of a data types makes them more abstract in such a way that we hide their implementation. Also, whoever uses our module can't pattern match against the value constructors. This is why previously we get compilation error in the Geometry module.
I hope this example will help you understand the reason for such errors.

Related

Solutions for "multiple declarations" in Haskell sum data types?

GHC 9.2.4 gives a multiple declaration error for the following code:
data X = A | B | C
data Y = A | B | C
There are so many new extensions in GHC nowadays. Is there one that allows me to do the above (since it is semantically appropriate for my problem domain) or is the common solution still to prefix, like data X = XA | XB | XC ?
Even without any extensions, you can declare the two types in different modules. You say in a comment "I wish these things can be namespaced"; the module system is namespaces.
module X where
data X = A | B | C
module Y where
data Y = A | B | C
module OnlyUsesX where
import X
foo :: Char -> Maybe X
foo 'a' = Just A
foo 'b' = Just B
foo 'c' = Just C
foo _ = Nothing
module UsesBoth where
import X (X) -- import only the type name unqualified, since
-- it's unambiguous
import qualified X as X -- also import the entire module qualified, for
-- the ambiguous stuff
import Y (Y)
import qualified Y as Y -- the "as Y" is pointless here, but normally the
-- full module name is longer; if you use the type
-- name as the module alias, then it looks like you
-- have a namespace associated with the type, much
-- like OO code
foo :: X -> Y -> String
foo X.A Y.A = "both A"
foo X.B Y.B = "both B"
foo _ _ = "I can't be bothered enumerating the rest of the possibilities"
If you put your types in small modules dedicated to just that one type, then in other modules where you use multiple types you can refer to the types as simply X or Y, and constructors/fields of the type as X.whatever
or Y.whatever.
This lets you use short prefixless names in the constructor/field names themselves (which avoids the prefixes infecting derived read/show/json/etc instances, if you care about that). Where there isn't any usage of conflicting names you have the option of importing unqualified and dropping the prefixes, which you wouldn't have if the prefix was baked into the actual constructor/field names. And it also avoids any ambiguous inference problems that a hypothetical version of GHC would necessarily have if it allowed duplicate constructor/pattern names in the same namespace and tried to use types to resolve which is which; if you ever use conflicting imported names in the same namespace the compiler will tell you and you can just use the module prefix to resolve it for the benefit of both the compiler and any human readers.
You should prefix them, or put them in separate modules. And probably you should also use them this explicitly qualified way.
However if you insist, you can fake constructors that are polymorphic to work for both cases, by using a type class and constructing patterns synonyms over it. In this case, the easiest way is to use the fact that both of these are isomorphic to X:
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE ViewPatterns #-}
class HasABCConstructors w where
fromX :: X -> w
toX :: w -> X
instance HasABCConstructors X where
fromX = id
toX = id
instance HasABCConstructors Y where
fromX XA = YA
fromX XB = YB
fromX XC = YC
toX YA = XA
toX YB = XB
toX YC = XC
pattern A :: HasABCConstructors w => w
pattern A <- (toX -> XA)
where A = fromX XA
ghci> A :: X
XA
ghci> A :: Y
YA

Construct a dependent type out of a list in Haskell

I want to write a library in Haskell for Galois fields. A Galois field is defined by its irreducible polynomial. Galois field elements can only be added if they have the same Galois field. I want to lift the polynomial into the type of my Galois field, so that for example a Galois field with the polynomial [1, 2, 3] has a different type than a Galois Field with the polynomial [2, 0, 1]. This way i could assure that only Galois field elements with the same Galois field can be added. Is this possible?
My polynomial data type looks like this:
newtype Polynomial a = Polynomial [a]
My Galois field data type look like this:
data GF irr a = GF {
irreducible :: irr
, q :: PrimePower
}
So i want a constructor that takes a polynomial (for example (Polynomial [2, 0, 1])) and gives me a Galois field of the type GF (Polynomial Int) ([2, 0, 1]).
I know that [2, 0, 1] is not a valid type but i saw that with Data.Singletons it is possible to create types like
(SCons STrue (SCons SFalse SNil))
for [True, False], but i do not know how to construct types likes these from my list [2, 0, 1] and how the constructor would look like.
As Luke already commented, [2, 0, 1] is actually a valid type.
Prelude> :set -XDataKinds -XPolyKinds
Prelude> data A x = A deriving Show
Prelude> A :: A [2,0,1]
A
where the number literals are actually type-level Nat literals, and [...] is a lifted version of the list value-constructor to the type kind. This can be made explicit by writing it with “prime-quote syntax”
Prelude> A :: A '[2, 0, 1]
A
...so, this task is actually pretty trivial. You can just use
{-# LANGUAGE DataKinds, KindSignatures #-}
import GHC.TypeLits (Nat)
newtype Polynomial a = Polynomial [a]
data GF (irr :: Polynomial Nat) = GF {q :: PrimePower}
As also said by Luke, keep in mind though that type-level calculations don't work as well as they do in full dependently-typed languages. If you really want to do proof stuff with this, you should consider switching to Idris, Agda or Coq.
It seems that the "lifted" value will be used merely as a tag. For cases in which we only want it to work as a tag, but it's difficult to lift the required value to the type level with DataKinds, a possible alternative consists in attaching to the value a "ghostly" type tag conjured by means of a polymorphic incantation. Consider this helper module:
{-# LANGUAGE RankNTypes #-}
module Named (Named,forgetName,name) where
newtype Named n a = Named a -- don't export the constructor
forgetName :: Named n a -> a
forgetName (Named a) = a
name :: a -> ( forall name. Named name a -> r ) -> r
name x f = f ( Named x ) -- inside the callback, "x" has a "name" type tag attached
And this other module which depends on it:
module GF (Polynomial(..),GF,stuff,makeGF,addGF) where
import Named
newtype Polynomial a = Polynomial [a]
data GF a = GF { -- dont' export the constructor
_stuff :: Int -- don't export the bare field
}
stuff :: GF a -> Int
stuff (GF x) = x
makeGF :: Named ghost (Polynomial Int) -> Int -> GF ghost
makeGF _ = GF
addGF :: Named ghost (Polynomial Int) -> GF ghost -> GF ghost -> GF ghost
addGF _ x1 x2 = GF (stuff x1 + stuff x2)
I would be impossible for clients of this module to sum two GF values with different ghostly tags. Their only way of creating ghostly tags is through name, and they don't have the means of re-tagging either the Named values or the GF ones—we carefully hid constructors and bare fields to prevent that. So this would compile:
module Main where
import Named
import GF
main :: IO ()
main = print $
name (Polynomial [2::Int,3,4]) $ \ghost ->
let x1 = makeGF ghost 3
x2 = makeGF ghost 4
in stuff (addGF ghost x1 x2)
But this wouldn't:
main :: IO ()
main = print $
name (Polynomial [2::Int,3,4]) $ \ghost1 ->
name (Polynomial [3::Int]) $ \ghost2 ->
let x1 = makeGF ghost1 3
x2 = makeGF ghost2 4
in stuff (addGF ghost1 x1 x2)

Combining Tuples in SBV?

Basically I'm wondering, is there any way to write a function of the following type with the SBV library:
(SBV a, SBV b) -> SBV (a,b)
This seems like it should be possible: if we have two symbolic values, we can make a new symbolic value, as a concrete pair whose elements are either the symbolic or concrete values of the two inputs. But I can't find anything like this, and the SBV type does not have its constructors exposed.
Is this possible?
Sounds like you need the tuple function. Here's an example:
import Data.SBV
import Data.SBV.Tuple
tup :: (SymVal a, SymVal b) => (SBV a, SBV b) -> SBV (a, b)
tup = tuple
tst :: Predicate
tst = do x <- sInteger "x"
y <- sInteger "y"
z <- sTuple "xy"
return $ tup (x, y) .== z
Of course, tuple itself can handle arity upto 8; the above is just one instantiation at the exact type you wanted. We have:
$ ghci a.hs
GHCi, version 8.6.4: http://www.haskell.org/ghc/ :? for help
[1 of 1] Compiling Main ( a.hs, interpreted )
Ok, one module loaded.
*Main> sat tst
Satisfiable. Model:
x = 0 :: Integer
y = 1 :: Integer
xy = (0,1) :: (Integer, Integer)
There's also the untuple function that goes in the other direction. They are both in the Data.SBV.Tuple module that you have to explicitly import. (You can also find lens-like accessors in the same module, which lets you write, ^._1, ^._2 etc. to extract fields of tuples; as in z^._2 for the above example.)

Hide a constructor but not the type on import

I've got an internal module I'd like to provide an external API for
module Positive.Internal where
newtype Positive a = Positive { getPositive :: a }
deriving (Eq, Ord)
-- smart constructor
toPositive :: (Num a, Ord a) => a -> Maybe (Positive a)
toPositive a | a <= 0 = Nothing
| otherwise = Just $ Positive a
-- ...
I want to hide the dumb constructor, and replace it with a unidirectional
pattern so users can still pattern match values, they just have to use the smart constructor to use new values.
Since I want the pattern and the dumb constructor to use the same name, I need to hide the dumb constructor to prevent namespace clashes.
However, since the dumb constructor and the type share names, it's a little tricky to import the everything BUT the dumb constructor.
Currently I'm doing this, which works ok:
{-# LANGUAGE PatternSynonyms #-}
module Positive
( module Positive.Internal, pattern Positive
) where
import Positive.Internal (Positive())
import Positive.Internal hiding (Positive)
import qualified Positive.Internal as Internal
pattern Positive :: a -> Positive a
pattern Positive a <- Internal.Positive a
I could simplify my imports by just using the qualified import, but I'm curious.
Is there a way to, in a single import statement, import all of Positive.Internal except the dumb constructor?
I tried hiding (Positive(Positive)), but that hid both the type and the dumb constructor. I've poked about the wiki, but I haven't noticed any way to differentiate between constructors and types in hiding lists.
Correct me if I am wrong, but I am almost certain this is what you are looking for:
{-# LANGUAGE PatternSynonyms #-}
module Positive
( module Positive.Internal, pattern Positive, foo
) where
import Positive.Internal hiding (pattern Positive)
import qualified Positive.Internal as Internal (pattern Positive)
pattern Positive :: a -> Positive a
pattern Positive a <- Internal.Positive a
foo :: Positive Int
foo = Internal.Positive 5
Internal module stays the same way as it is defined so far. And for the sake of example:
module Negative where
import Positive
bar :: Maybe Int
bar = getPositive <$> toPositive 6
Let's double check in GHCi:
Prelude> :load Negative
[1 of 3] Compiling Positive.Internal ( Positive/Internal.hs, interpreted )
[2 of 3] Compiling Positive ( Positive.hs, interpreted )
[3 of 3] Compiling Negative ( Negative.hs, interpreted )
Ok, modules loaded: Negative, Positive, Positive.Internal.
*Negative> bar
Just 6
*Negative> getPositive foo
5
*Negative> :i Positive
newtype Positive a = Positive.Internal.Positive {getPositive :: a}
-- Defined at Positive/Internal.hs:3:1
instance [safe] Ord a => Ord (Positive a)
-- Defined at Positive/Internal.hs:4:17
instance [safe] Eq a => Eq (Positive a)
-- Defined at Positive/Internal.hs:4:13
*Negative> :t Positive
<interactive>:1:1: error:
• non-bidirectional pattern synonym ‘Positive’ used in an expression
• In the expression: Positive

Haskell Import error: Not in scope

I have written this code:
import GHC.Float
next :: GHC.Float -> GHC.Float-> GHC.Float
next n x = (x + n / x) / 2
And I am getting the following error:
numerical.hs:3:9:
Not in scope: type constructor or class `GHC.Float'
numerical.hs:3:22:
Not in scope: type constructor or class `GHC.Float'
numerical.hs:3:34:
Not in scope: type constructor or class `GHC.Float'
The module imports without any problem, so I'm not sure if I'm referring to it with the wrong name or if the standard Float module is the same as the IEEE GHC.Float one and there's no need to explicitly import it.
I tried doing an import GHC.Float as Fl with no success--got the same type error on Fl.
I'm just starting Haskell (obviously), so any help is appreciated!
You don't have to import GHC.Float manually, you can just write Float, like so
next :: Float -> Float -> Float
next n x = (x + n / x) / 2
GHC implicitly imports a module called Prelude in every source file you have. Prelude includes a lot of handy types, functions, and other things that are used as the "built-ins" of the language. Types like Int, Float, Maybe, IO, and functions like head, +, /, and more.
You can test to see if a floating point number is an IEEE floating point with the function isIEEE from the GHC.Float module:
import GHC.Float
main = do
putStr "1.0 is an IEEE floating point: "
print $ isIEEE (1.0 :: Float)
If you run this, it will print True
I should have also mentioned that the reason why your code didn't compile earlier is because when you import a module with just import, everything from it comes into scope. You can force it to be qualified by using import qualified, here's a few examples:
import GHC.Float -- Everything now in scope
import qualified Data.Maybe -- Have to use full name
import qualified Data.List as L -- aliased to L
main = do
-- Don't have to type GHC.Float.isIEEE
print $ isIEEE (1.0 :: Float)
-- Have to use full name
print $ Data.Maybe.isJust $ Nothing
-- Uses aliased name
print $ L.sort [1, 4, 2, 5, 3]

Resources