Haskell - Type incompatibility after qualified import - haskell

I'm using hMatrix and the first lines of my code are:
import Numeric.LinearAlgebra
import qualified Data.Vector as V
The problem is that in my code the vector type is V.Vector, but some methods defined by hMatrix have type Vector -> ... and GHC does not understand when I try to use these methods, saying that they are not defined for the type V.Vector. How can I solve this problem?
Update:
From the documentation of hMatrix:
The Vector type is a Storable vector from Roman Leshchinskiy’s vector package, so all array processing tools provided by this library are directly available.
However, some basic operators like (++) (which is present in Data.Vector.Storable) are not included in hMatrix. Is it impossible to use these from hMatrix or is there some simple way to tell the compiler that these types are the same?

hmatrix uses its own Data.Packed.Vector type and it's different from Data.Vector.
Either using Data.Packed.Vector in your code, or converting Data.Vector to Data.Packed.Vector before calling functions would work.

You could add an explicit import for the Vector type:
import Numeric.LinearAlgebra
import qualified Data.Vector as V
import Data.Vector (Vector)
Though, I didn't know external modules could break depending on how you import modules they depend on.

Note that you can't break hmatrix just because you import another module. You just have a type mismatch as vector provides different types of vectors, including a .Generic interface that works for all of those.
You probably have something along the lines of
import Data.Vector
f :: Vector Int -> Vector Int
f = whatever
If you import Data.Vector.Generic you can write functions that work for all vector types, including those used by hmatrix.
import Data.Vector.Generic
f :: Vector Int -> Vector Int
f xs = xs ++ empty
should work with hmatrix vectors.

Related

Is there a way to define multiple type synonyms in a single line?

My code is currently like this:
type Speed = Float
type Height = Float
type FuelMass = Float
type Gravity = Float
is there a way to not be wasting so much space by grouping the declarations, like
type (Speed, Height, FuelMass, Gravity) = Float
No. A type definition is its own statement. If you really wanted to, you could group them on the same line by separating with semicolons instead of newlines, but this would be a very very unusual style.
Well, you can of course have any code generated for you by Template Haskell.
module MultiDefinitions where
import Language.Haskell.TH
import Control.Monad
multipleTypeSynonyms :: [Q Name] -> Q Type -> DecsQ
multipleTypeSynonyms synGs tG = do
t <- tG
forM synGs $ \synG -> do
syn <- synG
return $ TySynD syn [] t
Then
{-# LANGUAGE TemplateHaskell #-}
import Language.Haskell.TH
import MultiDefinitions
multipleTypeSynonyms
(newName <$> ["Speed", "Height", "FuelMass", "Gravity"]) [t| Float |]
will generate the same definitions you wrote manually.
Is it a good idea to du stuff like that with TH? Hardly. In fact it is also not clear that type synonyms like that are a good thing at all – many Haskellers would argue that you should either use newtypes that actually give additional type safety (or use existing library types, such as from the units library), or else simply hard-code Float.
BTW there's seldom a good reason to use Float, just use Double.

Dealing with ambiguous occurrence in Haskell

I'm importing both Data.Text and Data.List and their respective find functions collapse.
import Data.Text
import Data.List
my_list = [4, 2, 4, 5, 6, 2, 6]
find (\a -> a == 5) my_list
The above code leads to the following error
Ambiguous occurrence ‘find’
It could refer to
either ‘Data.Text.find’, imported from ‘Data.Text’
or ‘Data.List.find’,
imported from ‘Data.List’
(and originally defined in ‘Data.Foldable’)
Is the only solution to use Data.List.find (\a -> a == 5) my_list here, or qualified imports?
What strikes me is that
Data.List.find (\a -> a == 5) my_list
--> Just 5
Data.Text.find (\a -> a == 5) my_list
--> error: Couldn't match expected type ‘Text’ with actual type ‘[Integer]’
From the find function signatures, the compiler is apparently able to understand that Data.Text.find doesn't work with [Integer]. Can't he use this information to decide on which instance of find to use and, in this case, automatically use find from Data.List ?
Is the only solution to use Data.List.find (\a -> a == 5) my_list here, or qualified imports?
As far as I know, yes, there are no other solutions.
The compiler won't try to type-check both options and use the one which makes your code compile. In the most general case, that could lead to an exponential blow-up. Consider, e.g.,
foo a1 a2 .... aN
where each one of a1 .. aN are imported from two distinct modules. Trying which combination type-checks would in principle require to test 2^N combinations.
Further, there's always the chance that the programmer meant to use an identifier from a module, but they made a mistake and the code does not type-check. In this case, the same identifier from the other module might instead type-check, making the code compile but producing the wrong result. (This is a rather contrived example, I know.)
Note that, if in your importing module you only need to use one of the two finds you can hide the other:
import Data.Text hiding (find)
import Data.List
Alternatively, you can provide explicit disjoint import lists:
import Data.Text (pack)
import Data.List (find, zip)
If you need both finds, you can provide a shorter name for the module
import Data.Text as T
import Data.List as L
as then disambiguate using L.find. You won't need the shorter module name except for the doubly imported identifiers. If you use import qualified instead you will need to specify the module name for all imported identifiers.

Is there an inplace map function for mutable vectors?

If I have a mutable vector (with type IOVector a for example), is there a map-like function that can modify the elements in place?
The vector package provides the modify function but this is only one element at a time. Should I use this or is there a preferred method?
And to clarify, the type of the vector will be the same before and after.
Yep, use modify if you want to modify elements in place. If you find yourself often modifying everything in place, you can define mapModify as follows.
import Data.Foldable (for_)
import qualified Data.Vector.Mutable as MV
mapModify :: (a -> a) -> IOVector a -> IO ()
mapModify f v = for_ [0 .. MV.length v - 1)] (MV.modify v f)
That said, constantly modifying all elements in a vector sounds like you may be better off using immutable vectors and mapping over them using the regular fmap. If that code ends up fusing properly, the intermediate vectors will never even be materialized.

Haskell converting between vector types

I'm starting to learn Haskell, but I'm finding it hard to figure out the small, little things that the tutorials jumps over. Right now I'm working with tuples in the form of Vector.Fixed:
import qualified Data.Vector.Fixed as VF
import qualified Data.Vector.Fixed.Unboxed (Vec 2)
import qualified Data.Vector.Unboxed as VU
let a = VF.mk2 7 7 :: (Int, Int)
let b = VF.mk2 7 7 :: (Vec2 Int)
What's difference between a and b?
How can I make a VF vector f equivalent of
[a, a] = [(7,7), (7,7)]?
How can I make a VU vector g equivalent of [[a], [a,a]] = [[(7,7)], [(7,7), (7,7)]]?
For question 2 and 3, I can't get past the type errors when trying to use the convert function.
I know that my tuples always will be of length 2, but I need a list
(or whatever) f of tuples that can be fixed size, and another g
that is two-dimensional (e.g. [[(1,2),(3,4)],[(1,2)]] where
neither the top list nor the sub lists can be of fixed size. Should
I stick to the same type for f and g?
Data.Vector.Fixed and Data.Vector.Unboxed both seem to come from the
same package, but they have different maintainers. Are they both
official, so to speak, or do they not share any similarities other
than that they both are vector implementations?

Explicitly import instances

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.

Resources