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

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.

Related

What is this type?

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.

Polymorphic return types and "rigid type variable" error in Haskell

There's a simple record Column v a which holds a Vector from the Data.Vector family (so that v can be Vector.Unboxed, just Vector etc), it's name and type (simple enum-like ADT SupportedTypes). I would like to be able to serialize it using the binary package. To do that, I try to define a Binary instance below.
Now put works fine, however when I try to define deserialization in the get function and want to set a specific type to the rawVector that is being returned based on the colType (U.Vector Int64 when it's PInt, U.Vector Double when it's PDouble etc) - I get this error message:
Couldn't match type v with U.Vector
v is a rigid type variable bound by the instance declaration at src/Quark/Base/Column.hs:75:10
Expected type: v a
Actual type: U.Vector Int64
error.
Is there a better way to achieve my goal - deserialize Vectors of different types based on the colType value or am I stuck with defining Binary instance for all possible Vector / primitive type combinations? Shouldn't be the case...
Somewhat new to Haskell and appreciate any help! Thanks!
{-# LANGUAGE OverloadedStrings, TransformListComp, RankNTypes,
TypeSynonymInstances, FlexibleInstances, OverloadedLists, DeriveGeneric #-}
{-# LANGUAGE MultiParamTypeClasses, FlexibleContexts,
TypeFamilies, ScopedTypeVariables, InstanceSigs #-}
import qualified Data.Vector.Generic as G
import qualified Data.Vector.Unboxed as U
data Column v a = Column {rawVector :: G.Vector v a => v a, colName :: Text, colType :: SupportedTypes }
instance (G.Vector v a, Binary (v a)) => Binary (Column v a) where
put Column {rawVector = vec, colName = cn, colType = ct} = do put (fromEnum ct) >> put cn >> put vec
get = do t <- get :: Get Int
nm <- get :: Get Text
let pt = toEnum t :: SupportedTypes
case pt of
PInt -> do vec <- get :: Get (U.Vector Int64)
return Column {rawVector = vec, colName = nm, colType = pt}
PDouble -> do vec <- get :: Get (U.Vector Double)
return Column {rawVector = vec, colName = nm, colType = pt}
UPDATED Thank you for all the answers below, some pretty good ideas! It's quite clear that what I want to do is impossible to achieve head-on - so that is my answer. But the other suggested solutions are a good reading in itself, thanks a bunch!
The type you are really trying to represent is
data Column v = Column (Either (v Int) (v Double))
but this representation may be unsatisfactory to you. So how do you write this type with the vector itself at the 'top level' of the constructor?
First, start with a representation of your sum (Either Int Double) at the type level, as opposed to the value level:
data IsSupportedType a where
TInt :: IsSupportedType Int
TDouble :: IsSupportedType Double
From here Column is actually quite simple:
data Column v a = Column (IsSupportedType a) (v a)
But you'll probably want a existentially quantified to use it how you want:
data Column v = forall a . Column (IsSupportedType a) (v a)
The binary instance is as follows:
instance (Binary (v Int), Binary (v Double)) => Binary (Column v) where
put (Column t v) = do
case t of
TInt -> put (0 :: Int) >> put v
TDouble -> put (1 :: Int) >> put v
get = do
t :: Int <- get
case t of
0 -> Column TInt <$> get
1 -> Column TDouble <$> get
Note that there is no inherent reliance in Vector here - v could really be anything.
The problem you're actually running into (or if you're not yet, that you will) is that you're trying to decide a resulting type from an input value. You cannot do that. At all. You could cleverly lock the result type in a box and throw away the key so the type appears to be normal from the outside, but then you cannot do anything much with it because you locked the type in a box and threw away the key. You can store extra information about it using GADTs and boxing it up with a type class instance, but even still this is not a great idea.
Your could make your life far easier here if you simply had two constructors for Column to reflect whether there was a vector of Ints or Doubles.
But really, don't do any of that. Just let the automatically derivable Binary instance deserialize any deserializable value into your vector for you.
data Column a = ... deriving (Binary)
Using the DeriveAnyClass extension that let's you derive any class that has a Generic implementation (which Binary has). Then just deserialize a Column Double or a Column Int when you need it.
As the comment says, you can simply not case on the type, and always call
vec <- get
return Column {rawVector = vec, colName = nm, colType = pt}
This fulfills your type signature properly. But note that colType is not useful to you here -- you have no way to enforce that it corresponds to the type within your vector, since it only exists at the value level. But that may be ok, and you may simply want to remove colType from your data structure altogether, since you can always derive it directly from the concrete type of a chosen in Column v a.
In fact, the constraint in the Column type isn't doing much good either, and I think it would be better to render it just as
data Column v a = Column {rawVector :: v a, colName :: Text}
Now you can just enforce the G.Vector constraint at call sites where necessary...

Haskell function returning existential type

Is it possible to write a Haskell function that yields a parameterised type where the exact type parameter is hidden? I.e. something like f :: T -> (exists a. U a)? The obvious attempt:
{-# LANGUAGE ExistentialQuantification #-}
data D a = D a
data Wrap = forall a. Wrap (D a)
unwrap :: Wrap -> D a
unwrap (Wrap d) = d
fails to compile with:
Couldn't match type `a1' with `a'
`a1' is a rigid type variable bound by
a pattern with constructor
Wrap :: forall a. D a -> Wrap,
in an equation for `unwrap'
at test.hs:8:9
`a' is a rigid type variable bound by
the type signature for unwrap :: Wrap -> D a at test.hs:7:11
Expected type: D a
Actual type: D a1
In the expression: d
In an equation for `unwrap': unwrap (Wrap d) = d
I know this is a contrived example, but I'm curious if there is a way to convince GHC that I do not care for the exact type with which D is parameterised, without introducing another existential wrapper type for the result of unwrap.
To clarify, I do want type safety, but also would like to be able to apply a function dToString :: D a -> String that does not care about a (e.g. because it just extracts a String field from D) to the result of unwrap. I realise there are other ways of achieving it (e.g. defining wrapToString (Wrap d) = dToString d) but I'm more interested in whether there is a fundamental reason why such hiding under existential is not permitted.
Yes, you can, but not in a straightforward way.
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE RankNTypes #-}
data D a = D a
data Wrap = forall a. Wrap (D a)
unwrap :: Wrap -> forall r. (forall a. D a -> r) -> r
unwrap (Wrap x) k = k x
test :: D a -> IO ()
test (D a) = putStrLn "Got a D something"
main = unwrap (Wrap (D 5)) test
You cannot return a D something_unknown from your function, but you can extract it and immediately pass it to another function that accepts D a, as shown.
Yes, you can convince GHC that you do not care for the exact type with which D is parameterised. Just, it's a horrible idea.
{-# LANGUAGE GADTs #-}
import Unsafe.Coerce
data D a = D a deriving (Show)
data Wrap where -- this GADT is equivalent to your `ExistentialQuantification` version
Wrap :: D a -> Wrap
unwrap :: Wrap -> D a
unwrap (Wrap (D a)) = D (unsafeCoerce a)
main = print (unwrap (Wrap $ D "bla") :: D Integer)
This is what happens when I execute that simple program:
and so on, until memory consumption brings down the system.
Types are important! If you circumvent the type system, you circumvent any predictability of your program (i.e. anything can happen, including thermonuclear war or the famous demons flying out of your nose).
Now, evidently you thought that types somehow work differently. In dynamic languages such as Python, and also to a degree in OO languages like Java, a type is in a sense a property that a value can have. So, (reference-) values don't just carry around the information needed to distinguish different values of a single type, but also information to distinguish different (sub-)types. That's in many senses rather inefficient – it's a major reason why Python is so slow and Java needs such a huge VM.
In Haskell, types don't exist at runtime. A function never knows what type the values have it's working with. Only because the compiler knows all about the types it will have, the function doesn't need any such knowledge – the compiler has already hard-coded it! (That is, unless you circumvent it with unsafeCoerce, which as I demonstrated is as unsafe as it sounds.)
If you do want to attach the type as a “property” to a value, you need to do it explicitly, and that's what those existential wrappers are there for. However, there are usually better ways to do it in a functional language. What's really the application you wanted this for?
Perhaps it's also helpful to recall what a signature with polymorphic result means. unwrap :: Wrap -> D a doesn't mean “the result is some D a... and the caller better don't care for the a used”. That would be the case in Java, but it would be rather useless in Haskell because there's nothing you can do with a value of unknown type.
Instead it means: for whatever type a the caller requests, this function is able to supply a suitable D a value. Of course this is tough to deliver – without extra information it's just as impossible as doing anything with a value of given unknown type. But if there are already a values in the arguments, or a is somehow constrained to a type class (e.g. fromInteger :: Num a => Integer -> a, then it's quite possible and very useful.
To obtain a String field – independent of the a parameter – you can just operate directly on the wrapped value:
data D a = D
{ dLabel :: String
, dValue :: a
}
data Wrap where Wrap :: D a -> Wrap
labelFromWrap :: Wrap -> String
labelFromWrap (Wrap (D l _)) = l
To write such functions on Wrap more generically (with any “ label accesor that doesn't care about a”), use Rank2-polymorphism as shown in n.m.'s answer.

How to define a function inside haskell newtype?

I am trying to decipher the record syntax in haskell for newtype and my understanding breaks when there is a function inside newtype. Consider this simple example
newtype C a b = C { getC :: (a -> b) -> a }
As per my reasoning C is a type which accepts a function and a parameter in it's constructor.
so,
let d1 = C $ (2 *) 3
:t d1 also gives
d1 :: Num ((a -> b) -> a) => C a b
Again to check this I do :t getC d1, which shows this
getC d1 :: Num ((a -> b) -> a) => (a -> b) -> a
Why the error if I try getC d1? getC should return the function and it's parameter or at least apply the parameter.
I can't have newtype C a b = C { getC :: (a->b)->b } deriving (Show), because this won't make sense!
It's always good to emphasise that Haskell has two completely separate namespaces, the type language and the value language. In your case, there's
A type constructor C :: Type -> Type -> Type, which lives in the type language. It takes two types a, b (of kind Type) and maps them to a type C a b (also of kind Type)†.
A value constructor C :: ((a->b) -> a) -> C a b, which lives in the value language. It takes a function f (of type (a->b) -> a) and maps it to a value C f (of type C a b).
Perhaps it would be less confusing if you had
newtype CT a b = CV ((a->b) -> a)
but because for a newtype there is always exactly one value constructor (and exactly one type constructor) it makes sense to name them the same.
CV is a value constructor that accepts one function, full stop. That function will have signature (a->b) -> a, i.e. its argument is also a function, but as far as CT is concerned this doesn't really matter.
Really, it's kind of wrong that data and newtype declarations use a = symbol, because it doesn't mean the things on the left and right are “the same” – can't, because they don't even belong to the same language. There's an alternative syntax which expresses the relation better:
{-# LANGUAGE GADTs #-}
import Data.Kind
data CT :: Type -> Type -> Type where
CV :: ((a->b) -> a) -> CT a b
As for that value you tried to construct
let d1 = CV $ (\x->(2*x)) 3
here you did not pass “a function and a parameter” to CV. What you actually did‡ was, you applied the function \x->2*x to the value 3 (might as well have written 6) and passed that number to CV. But as I said, CV expects a function. What then happens is, GHC tries to interpret 6 as a function, which gives the bogus constraint Num ((a->b) -> a). What that means is: “if (a->b)->a is a number type, then...”. Of course it isn't a number type, so the rest doesn't make sense either.
†It may seem redundant to talk of “types of kind Type”. Actually, when talking about “types” we often mean “entities in the type-level language”. These have kinds (“type-level types”) of which Type (the kind of (lifted) value-level values) is the most prominent, but not the only one – you can also have type-level numbers and type-level functions – C is indeed one.Note that Type was historically written *, but this notation is deprecated because it's inconsistent (confusion with multiplication operator).
‡This is because $ has the lowest precedence, i.e. the expression CV $ (\x->(2*x)) 3 is actually parsed as CV ((\x->(2*x)) 3), or equivalently let y = 2*3 in CV y.
As per my reasoning C is a type which accepts a function and a parameter
How so? The constructor has only one argument.
Newtypes always have a single constructor with exactly one argument.
The type C, otoh, has two type parameters. But that has nothing to do with the number of arguments you can apply to the constructor.

writing a function that accepts multiple input and has multiple outputs in haskell

whats the correct way to write a function that can accept different input's and have different outputs
for example i'm using hmatrix and
lets say i want to accept a Matrix or a Vector in my function, and the output can be a Matrix or a Vector depending on hte formula
where T in the below example can be a matrix or a vector , is maybe the right tool for this?
Myfunc ::(Matrix A, Matrix/Vector T) -> Maybe(Matrix/Vector T)
Update using either mentioned below here is one possible solution
Myfunc :: Maybe Matrix Double t -> (Either Vector Double a,Matrix Double a) -> Either (Matrix Double T,Vector Double T)
Take a look at how matrix multiplication and left-divide are implemented in the source code for HMatrix.
Essentially, they define a multi-parameter type class which tells the function how to behave for different inputs, and it has a functional dependency which tells it what output is appropriate. For example, for multiplication:
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FunctionalDependencies #-}
-- |The class declaration 'Mul a b c' means "an 'a' multiplied by a 'b' returns
-- a 'c'". The functional dependency 'a b -> c' means that once 'a' and 'b' are
-- specified, 'c' is determined.
class Mul a b c | a b -> c where
-- | Matrix-matrix, matrix-vector, and vector-matrix products.
(<>) :: Product t => a t -> b t -> c t
-- |Matrix times matrix is another matrix, implemented using the matrix
-- multiplication function mXm
instance Mul Matrix Matrix Matrix where
(<>) = mXm
-- |Matrix times vector is a vector. The implementation converts the vector
-- to a matrix and uses the <> instance for matrix/matrix multiplication/
instance Mul Matrix Vector Vector where
(<>) m v = flatten $ m <> asColumn v
-- |Vector times matrix is a (row) vector.
instance Mul Vector Matrix Vector where
(<>) v m = flatten $ asRow v <> m
You could either have a look at Either (I know, it's a bad joke), or, if your function has a general meaning but different implementations on different data types, you could define a typeclass.
edit: I didn't add any further details because your question isn't completely clear to me
The question is what do you want to do with your input? For example if you want to do comparison then you can say input has to be of class Ord like this:
myFunc :: (Ord a) => a -> b
Another way would be to use Either, but in that case you can have only two different data types. For example
myFunc :: Either a b -> Either c d
can accept and return different types.
Another solution would be to use a list of lists [[a]]. Essentially a vector is a matrix with a single row.

Resources