What is this type? - haskell

Haskell novice here. I know from type classes that =>means "in the context of". Yet, I can't read the following type, found in module Statistics.Sample
(Vector v (Double, Double), Vector v Double) => v (Double, Double) -> Double
What constraints are being applied on v left of => ?

The Data.Vector.Generic.Vector typeclass takes two type arguments, v and a where v :: * -> * is the type of the container and a :: * is the type of the elements in the container. This is simply a generic interface for the vector types defined in the vector package, notably Data.Vector.Unboxed.Vector.
This is essentially saying that the type v must be able to hold (Double, Double) and Double, although not simultaneously. If you were to use v ~ Data.Vector.Unboxed.Vector then this works just fine. The reason is due to the implementation of correlation, which uses unzip. This function splits a v (a, b) into (v a, v b). Since correlation is working on v (Double, Double), it needs the additional constraint that v can hold Doubles.
This generic type is meant to make the correlation function work with more types than Data.Vector.Vector, including any vector style types that might be implemented in other libraries.
I want to stress that these constraints
Data.Vector.Generic.Vector v (Double, Double)
Data.Vector.Generic.Vector v Double
State that whatever type you choose for v is capable of holding (Double, Double) and is also capable of holding Double. This is specifying certain prerequisites for your vector type, not the actual contents of the vector. The actual contents of the vector is specified in the first argument to the correlation function.

Related

How do I give a concrete value to a Haskell instance?

I'm trying to learn Haskell and I'm a bit confused by this infamous "rigid type variable" error.
Here's the relevant part of my code:
class Ord v => Vector v where
distance :: v -> v -> Double
-- with FlexibleInstances
instance Vector (Double, Double) where
distance (a,b) (c,d) = -- function definition omitted
data KMeansState v = KMeansState { centroids :: [v] }
test :: [(Double,Double)]
test = [(0,0),(1,1)] :: [(Double,Double)]
initializeState :: Vector v => Int -> KMeansState v
initializeState n = KMeansState test
The specific complaint that the compiler is giving me:
• Couldn't match type ‘v’ with ‘(Double, Double)’
‘v’ is a rigid type variable bound by
the type signature for:
initializeState :: forall v.
Vector v =>
Int -> Double -> KMeansState v
at Chapter06.hs:32:1-61
Expected type: KMeansState v
Actual type: KMeansState (Double, Double)
My understanding is that the compiler is saying my initializeState function needs to be able to return (or whatever the right word is in Haskell) a KMeansState whose type parameter is any type that's an instance of Vector, while the actual implementation of my function will only return one type, namely a KMeansState (Double, Double).
What I'm not clear on is how to get a "concrete" value out of this initializeState function. At some point in the program, I need to give the KMeansState constructor an actual value which will have an actual type, and it seems like the compiler is saying that I can't do that.
I'm further confused by why the code compiles if I hard code the value of the test function into initializeState. That is, this successfully type-checks, even though the value being passed to the KMeansState function should be functionally the same.
class Ord v => Vector v where
distance :: v -> v -> Double
-- with FlexibleInstances
instance Vector (Double, Double) where
distance (a,b) (c,d) = -- function definition omitted
data KMeansState v = KMeansState { centroids :: [v] }
-- test :: [(Double,Double)]
-- test = [(0,0),(1,1)] :: [(Double,Double)]
initializeState :: Vector v => Int -> KMeansState v
initializeState n = KMeansState [(0,0),(1,1)]::[(Double,Double)]
Can someone please clarify what's going on here and how I get this to compile? Thanks!
This is a common, fundamental misunderstanding about what Haskell typeclasses are / how they work. Concretely, a Haskell class is not like a class in OO languages. It is in some ways like an interface / abstract class, but that too not really.
In particular, you can't have “concrete values of a class”. Classes don't have values, they have instances – but those are types, not values. (These types then may or may not have values – in fact, strictly speaking they don't need to be types at all, just type-level entities.)
What you intend to say with your signature to the initializeState function is “the result is a value of type KMeansState v, where v is some type that is an instance of the Vector class but I don't want to tell you which”. What it actually says is, “for any type v that you pick, provided it is an instance of the Vector class, initializeState is a function that yields a KMeansState v value”. Because of the “for any”, aka “forall” or ∀, we call this a universally quantified type.
The intended type meanwhile is existentially quantified. It's a bit weird why this would be called so; it's a bit more understandable if I phrase it as “the result is a value r for which there exists a type v that has a Vector instance, such that r has the type KMeansState v”.
While Haskell has always had universally quantified types, it doesn't really have existential ones. What you can do is wrap an existential in a custom type:
{-# LANGUAGE GADTs #-}
data SomeVectorMeanState where
SomeVectorMeanState :: Vector v => KMeansState v -> SomeVectorMeanState
initializeState :: Int -> SomeVectorMeanState
initializeState n = SomeVectorMeanState $ KMeansState test
But this doesn't really accomplish anything useful. In fact, you won't be able to use the vector values in any way whatsoever, because the concrete type isn't known. See https://lukepalmer.wordpress.com/2010/01/24/haskell-antipattern-existential-typeclass/
Instead, as Willem Van Onsem commented, you should probably just use
initializeState :: Int -> KMeansState (Double,Double)
or, if you don't want to make it so obvious that the vector type is (Double,Double), you can wrap it in a type or newtype.

Haskell: how to write code that interacts with the internals of two wrapped types?

I'm wondering how to create two encapsulated types that interact with each other, without exposing the internal implementation to other modules.
As an example, consider my two modules, Vector.hs and Matrix.hs, that wrap Linear.V4 (a 4-element vector) and Linear.M44 (a 4x4 element matrix). I wish to write a function that multiplies a Matrix by a Vector, returning a Vector, and using the wrapped data types to perform the operation.
In this example, in Vector.hs I have:
-- Vector.hs
module Vector (Vector, vector) where
import Linear (V4 (V4))
newtype Vector = Vector (V4 Double) deriving (Eq, Show, Read)
vector :: (Double, Double, Double, Double) -> Vector
vector (x, y, z, w) = Vector (V4 x y z w)
Note that I'm only exporting the new type and the factory function - the data constructor Vector is not exported. As far as I understand, this hides the internal implementation of Vector (i.e. that it's really a V4).
And in Matrix.hs I have something similar:
-- Matrix.hs
module Matrix (Matrix, vector)
import Linear (V4 (V4), M44)
type Row = (Double, Double, Double, Double)
newtype Matrix = Matrix (M44 Double) deriving (Eq, Show, Read)
matrix :: (Row, Row, Row, Row) -> Matrix
--matrix ((a00, a01, a02, a03), (a10, ... ) = Matrix (V4 (V4 a00 a01 a02 a03) (V4 a10 ...))
These two modules can be used by client code pretty effectively - the client code is not aware that they are implemented with Linear data structures, and there's apparently no way for client code to exploit that (is that true?).
The problem arises when those two types need to interact with each other at the level of their wrapped types - in this particular case, multiplying a Matrix by a Vector yields a new Vector. However to implement this operation, the code performing it needs access to the internal implementation of both Vector and Matrix, in order to do something like this:
-- Matrix.hs
-- ... include earlier definitions
{-# LANGUAGE FlexibleInstances #-}
import qualified Linear.Matrix ((!*))
class MatrixMultiplication a b c | a b -> c where
infixl 7 |*| -- set same precedence and associativity as *
(|*|) :: a -> b -> c
instance MatrixMultiplication Matrix Vector Vector where
(|*|) (Matrix a) q0 =
let (V4 x y z w) = a Linear.Matrix.!* _impl q0
in vector (x, y, z, w)
To do this I need a function, _impl, that allows the Matrix module to get at the internals of Vector:
-- Vector.hs
-- ... include earlier definitions
_impl :: Vector -> V4 Double
_impl (Vector q) = q
-- also added to export list
So after carefully hiding the internals of Vector (by not exporting the data constructor function of Vector), it seems I must expose them with a different exported function, and the only defence I have is some documentation telling client code they shouldn't be using it. This seems unfortunate - I've effectively just renamed the data constructor.
In a language like C++, the friend keyword could be used to provide a function access to the private data member of one of the types. Is there a similar concept in Haskell?
I suppose I could implement both Vector and Matrix in the same module. They'd then have access to each others' data constructors. However this isn't really a satisfying solution as it just works around the issue.
Is there a better approach?

Why does (-) fail to typecheck when I place a Double Matrix on the left and a Double on the right?

Since hmatrix provides an instance of Num for Matrix types, I can express element-wise subtraction like:
m = (2><2)[1..] :: Double Matrix
m' = m - 3
That works great, as 3 is a Num, and results in a matrix created by subtracting 3 from each element of m.
Why does this not also work:
m' = m - (3::Double)
The error I'm getting is:
Couldn't match expected type ‘Matrix Double’
with actual type ‘Double’
In the second argument of ‘(-)’, namely ‘(3 :: Double)’
In the expression: m - (3 :: Double)
I expected the compiler to understand that a Double is also a Num. Why is that seemingly not the case?
What happens when you do m - 3 with m :: Matrix Double is that 3 :: Matrix Double. The fact that Matrix Double is an instance of Num means that the compilers knows how to translate the litteral 3. However when you do m - (3 :: Double), you get a type error because (-) :: (Num a) => a -> a -> a, so the type of the element you subtract must be instances of Num and match. Hence you can subtract two Doubles, two Matrix Doubles but not a Matrix Double and a Double.
After all, this seems fairly logical to me, it doesn't make sense to subtract a matrix and a scalar.
This is a common misunderstanding of people new to Haskell's style of typeclass based overloading, especially those who are used to the subclass-based overloading used in popular OO languages.
The subtraction operator has type Num a => a -> a -> a; so it takes two arguments of any type that is in the type class Num. It seems like what is happening when you do m - 3 is that the subtraction operator is accepting a Matrix Double on the left and some simple numeric type on the right. But that is actually incorrect.
When a type signature like Num a => a -> a -> a uses the same type variable multiple times, you can pick any type you like (subject to the contstraints before the =>: Num a in this case) to use for a but it has to be the exact same type everywhere that a appears. Matrix Double -> Double -> ??? is not a valid instantiation of the type Num a => a -> a -> a (and if it were, how would you know what it returned?).
The reason m - 3 works is that because both arguments have to be the same type, and m is definitely of type Matrix Double, the compiler sees that 3 must also be of type Matrix Double. So instead of using the 3 appearing in the source text to build a Double (or Integer, or one of many other numeric types), it uses the source text 3 to build a Matrix Double. Effectively the type inference has changed the way the compiler reads the source code text 3.
But if you use m' = m - (3::Double) then you're not letting it just figure out what type 3 must have to make the use of the subtraction operator valid, you're telling it that this 3 is specifically a Double. There's no way both facts to be true (your :: Double assertion and the requirement that the subtraction operator gets two arguments of the same type), so you get a type error.

How to allow unification of a type variable with different types?

I have a function with a following type signature
{-# LANGUAGE FlexibleContexts #-}
dataLat :: Load r DIM1 Double
=> (Array r DIM1 Double -> Array U DIM1 Double, Array U DIM1 Double)
Array, U and DIM1 come from Repa library. dataLat creates data that is later passed to other functions as a tuple. At one point r type variable gets unified with type D (this is again from Repa), but at later point r should also unify with type L (this is my type). The problem is that it has already been unified with D and cannot be therefore unified with L. I end up with Couldn't match expected type error. I think this should be solved by some form of higher rank types, but I am unable to figure out how this should be written. Can anyone give me a hand?
Try {-# LANGUAGE NoMonomorphismRestriction #-}
http://www.haskell.org/ghc/docs/7.6.1/html/users_guide/monomorphism.html
You can give dataLat a type saying that it returns a polymorphic function, using Rank2Types.
newtype Unboxer =
Unboxer {applyUnboxer :: forall repr. Load repr DIM1 Double => Array repr DIM1 Double -> Array U DIM1 Double}
dataLat :: (Unboxer, Array U DIM1 Double)
The body of dataLat must put a polymorphic function into Unboxer. The field accessor, applyUnboxer, returns a polymorphic function that can be used at different types.
It's not clear to me that you really need rank-2 types. Since dataLat takes no arguments, you can probably define the unboxer as a global function with ordinary rank-1 polymorphism.
To be precise, it doesn't make sense to unify a type variable with multiple types. To unify r with U and D would amount to saying that r == U and U == D, which is false. The code above allows a function to be instantiated to multiple types. Think of instantiation as making a copy of the code before assigning types, so you have one instance of the function where r₁ == U and a separate instance where r₂ == D.

Can I name a function signature?

I'm passing around a partially applied function. The full signature is:
import Data.Map as Map
-- Update the correct bin of the histogram based on the min value, bin width,
-- the histogram stored as a map, and the actual value we are interested in.
updateHist :: Double -> Double -> Map.Map Bin Double -> Double ->
Map.Map Bin Double
The function updates a Map which stores data for a histogram. The first two parameters give the bottom bounds of data we are interested, the next is the bin width for the histogram. I fill these values in when the program starts up and pass the partially applied function all over the module. This means I have a ton of functions with a signature like:
-- Extra the data out of the string and update the histogram (in the Map) with it.
doSomething :: String -> (Map.Map Bin Double -> Double -> Map.Map Bin Double) ->
Map.Map Bin Double
This is all fine and dandy, but writing "(Map.Map Bin Double -> Double -> Map.Map Bin Double)" is rather verbose. I'd like to replace them all with "UpdateHistFunc" as a type but for some reason I keep failing.
I tried:
newtype UpdateHistFunc = Map.Map Bin Double -> Double -> Map.Map Bin Double
This failed with the error:
HistogramForColumn.hs:84:44: parse error on input `->'
What am I doing wrong?
Are you confusing type and newtype here?
Using type defines a type synonym, which is what you seem to be trying to do, whereas newtype creates a new type that needs a constructor name, like with data.
In other words, you probably want this:
type UpdateHistFunc = Map.Map Bin Double -> Double -> Map.Map Bin Double
...or maybe this:
newtype UpdateHistFunc = UpdateHistFunc (Map.Map Bin Double -> Double -> Map.Map Bin Double)
The latter obviously needs to be "unwrapped" in order to apply the function.
For reference:
data defines a new algebraic data type, which can be recursive, have distinct instances of type classes, introduces an extra layer of possible laziness, all that stuff.
newtype defines a data type with a single constructor taking a single argument, which can be recursive and have distinct instances, but only for type checking; after compilation, it's equivalent to the type it contains.
type defines a type synonym, which can't be recursive or have distinct instances, is fully expanded when type checking, and amounts to little more than a macro.
If you're wondering about the semantic distinction between data and newtype where "extra laziness" is concerned, compare these two types and the possible values they can have:
data DType = DCon DType
newtype NType = NCon NType
For instance, what do you think these functions will do if applied to undefined vs. DCon undefined and NCon undefined, respectively?
fd (DCon x) = x
fn (NCon x) = x

Resources