What is this data ... where trying to accomplish? (Haskell) - haskell

In the random-fu package, there is this data declaration:
data Multinomial p a where
Multinomial :: [p] -> a -> Multinomial p [a]
I understand that this is a GADT, but what is it trying to accomplish? Is it placing restrictions on p or a, etc?

It changes the return type of the constructor. If it was defined like this
data Multinomial p a = Multinomial [p] a
our constructor would have the type
Multinomial :: [p] -> a -> Multinomial p a
The GADT changes the second type argument in the result type of the constructor to [a].

As for the "why", the Distribution type-class defines rvar as
class Distribution d t where
rvar :: d t -> RVar t
So the type parameter of the given distribution determines the type of the samples you get out of the RVar. So using the GADT, the Multinomial distribution is defined as one that always returns multiple values per sample even though it's constructed with just a single value of a.

Related

Can I attach a unique, run time determined tag to a selection of objects?

Consider type B and its subtype A, determined by a predicate P. An instance would be natural numbers for B and prime numbers for A, with some primality test as P. It is straightforward to implement a smart constructor for such A, defined as a newtype or a Tagged.
Now suppose the subtyping predicate is not completely determined at compile time. For example, let P be membership in a collection determined by IO input: the operator enters the coefficients for an integral polynomial and we obtain a predicate that verifies that a given number is a value of that polynomial at some index.
Can I make sure that each polynomial, and the values validated for it, are tagged in a fashion that makes them compatible with each other and incompatible with any other polynomial? Among the operations I am going to need is conversion between values and their indices, and I want to type safeguard them to avoid confusion.
This is how I imagine it to be:
polynomial :: [Integer] -> Polynomial unique
toValue :: Integer -> Polynomial unique -> Value unique
fromValue :: Integer -> Polynomial unique -> Maybe (Index unique)
toValue' :: Index unique -> Value unique
fromValue' :: Value unique -> Index unique
The point is to obtain these latter two total functions.
But I have no idea how to go about defining this polynomial function. Where would it get the unique type from?
To do it in an ST-like way you would need a library of functions to operate on the Value s and Polynomial s types, and then have a function with a type like this:
withPolynomial :: (forall s . Polynomial s -> Integer) -> [Integer] -> Integer
This will convert the [Integer] into a Polynomial s and pass it to the argument function. This function will then do whatever it wants, using your library of functions where appropriate. Any Value s values are guaranteed not to leak from the enclosing withPolynomial application, so they can't get mixed up. However this will also prevent you from storing polynomials and their values for use in future computations.

Practical applications of Rank 2 polymorphism?

I'm covering polymorphism and I'm trying to see the practical uses of such a feature.
My basic understanding of Rank 2 is:
type MyType = ∀ a. a -> a
subFunction :: a -> a
subFunction el = el
mainFunction :: MyType -> Int
mainFunction func = func 3
I understand that this is allowing the user to use a polymorphic function (subFunction) inside mainFunction and strictly specify it's output (Int). This seems very similar to GADT's:
data Example a where
ExampleInt :: Int -> Example Int
ExampleBool :: Bool -> Example Bool
1) Given the above, is my understanding of Rank 2 polymorphism correct?
2) What are the general situations where Rank 2 polymorphism can be used, as opposed to GADT's, for example?
If you pass a polymorphic function as and argument to a Rank2-polymorphic function, you're essentially passing not just one function but a whole family of functions – for all possible types that fulfill the constraints.
Typically, those forall quantifiers come with a class constraint. For example, I might wish to do number arithmetic with two different types simultaneously (for comparing precision or whatever).
data FloatCompare = FloatCompare {
singlePrecision :: Float
, doublePrecision :: Double
}
Now I might want to modify those numbers through some maths operation. Something like
modifyFloat :: (Num -> Num) -> FloatCompare -> FloatCompare
But Num is not a type, only a type class. I could of course pass a function that would modify any particular number type, but I couldn't use that to modify both a Float and a Double value, at least not without some ugly (and possibly lossy) converting back and forth.
Solution: Rank-2 polymorphism!
modifyFloat :: (∀ n . Num n => n -> n) -> FloatCompare -> FloatCompare
mofidyFloat f (FloatCompare single double)
= FloatCompare (f single) (f double)
The best single example of how this is useful in practice are probably lenses. A lens is a “smart accessor function” to a field in some larger data structure. It allows you to access fields, update them, gather results... while at the same time composing in a very simple way. How it works: Rank2-polymorphism; every lens is polymorphic, with the different instantiations corresponding to the “getter” / “setter” aspects, respectively.
The go-to example of an application of rank-2 types is runST as Benjamin Hodgson mentioned in the comments. This is a rather good example and there are a variety of examples using the same trick. For example, branding to maintain abstract data type invariants across multiple types, avoiding confusion of differentials in ad, a region-based version of ST.
But I'd actually like to talk about how Haskell programmers are implicitly using rank-2 types all the time. Every type class whose methods have universally quantified types desugars to a dictionary with a field with a rank-2 type. In practice, this is virtually always a higher-kinded type class* like Functor or Monad. I'll use a simplified version of Alternative as an example. The class declaration is:
class Alternative f where
empty :: f a
(<|>) :: f a -> f a -> f a
The dictionary representing this class would be:
data AlternativeDict f = AlternativeDict {
empty :: forall a. f a,
(<|>) :: forall a. f a -> f a -> f a }
Sometimes such an encoding is nice as it allows one to use different "instances" for the same type, perhaps only locally. For example, Maybe has two obvious instances of Alternative depending on whether Just a <|> Just b is Just a or Just b. Languages without type classes, such as Scala, do indeed use this encoding.
To connect to leftaroundabout's reference to lenses, you can view the hierarchy there as a hierarchy of type classes and the lens combinators as simply tools for explicitly building the relevant type class dictionaries. Of course, the reason it isn't actually a hierarchy of type classes is that we usually will have multiple "instances" for the same type. E.g. _head and _head . _tail are both "instances" of Traversal' s a.
* A higher-kinded type class doesn't necessarily lead to this, and it can happen for a type class of kind *. For example:
-- Higher-kinded but doesn't require universal quantification.
class Sum c where
sum :: c Int -> Int
-- Not higher-kinded but does require universal quantification.
class Length l where
length :: [a] -> l
If you are using modules in Haskell, you are already using Rank-2 types. Theoretically speaking, modules are records with rank-2 type properties.
For example, the Foo module below in Haskell ...
module Foo(id) where
id :: forall a. a -> a
id x = x
import qualified Foo
main = do
putStrLn (Foo.id "hello")
return ()
... can actually be thought as a record as follows:
type FooType = FooType {
id :: forall a. a -> a
}
Foo :: FooType
Foo = Foo {
id = \x -> x
}
P/S (unrelated this question): from a language design perspective, if you are going to support module system, then you might as well support higher-rank types (i.e. allow arbitrary quantification of type variables on any level) to reduce duplication of efforts (i.e. type checking a module should be almost the same as type checking a record with higher rank types).

Why are unconditionally ambiguous methods involving type families not rejected?

I have the following declarations:
class NN a where
type Vector a :: *
vectorize :: Vector a -> WordVector
compute :: a -> SomeResult
In an instance of NN, I have this:
instance NN Model where
type Vector Model = Vec
compute m = .... vectorize v ...
compute uses vectorize but this fails to typecheck: GHC says it cannot unifies Vector a0 with Vec and variable a0 is ambiguous.
I somehow understand why typechecking would fail in the general case of calling vectorize with only typeclass constraint: As type family Vector is open, there is no way, given a particular Vector a image to infer which a it is. Thanks to this answer I also can understand why it fail to typechecks in the particular case of a call from within a method defined in the same instance: At call site of vectorize there is no relationship between the a of Vector a -> WordVector and the a of compute.
What I don't understand is why the declaration of vectorize is not rejected by the compiler. Following this page and the referenced papers, I found the following statement in this paper:
Each method must mention the class variable somewhere that is not
under an associated synonym. For example, this declaration defines an
unconditionally-ambiguous method op, and is rejected:
class C a where
type S a
op :: S a → Int
Edit: I am using GHC 7.8.3

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.

Parameterizing types by integers in Haskell

I am trying to make some Haskell types which are parametrized not by types but by elements of a type, specifically, integers. For instance, a (linear-algebra) vector in R^2 and a vector in R^3 are different typed objects. Specifically, I am writing a K-D tree in Haskell and I want to parametrize my data-structure by a positive integer so a 3-D tree and 4-D tree have different type.
I've tried to parametrize my tree by tuples, but it didn't seem to be going anywhere (and it seems somewhat unlikely this can be pushed through, especially since it doesn't seem that triples or anything bigger are even functors (and I don't know any way to say like, instance HomogeneousTuple a => Functor a). I want to do something like this:
data (TupleOfDoubles a) => KDTree a b = ... ---so in a 3DTree a is (Double,Double,Double)
that would be nice, or something like this would be equally good
data KDTree Int a = ... -- The Int is k, so KDTree has kind Int -> * -> *
Does anybody know if either of these effects are workable or reasonable?
Thanks
-Joseph
There's a GHC extension being worked on called TypeNats, which would be exactly what you want. However the milestone for that is currently set to be 7.4.1 according to the ticket, so that'll be a bit of a wait still.
Until that extension is available, the only thing you can do is encode the dimension using types. For example something along these lines might work:
{-# LANGUAGE ScopedTypeVariables #-}
class MyTypeNat a where
toInteger :: a -> Integer
data Zero
data Succ a
instance MyTypeNat Zero where
toInteger _ = 0
instance MyTypeNat a => MyTypeNat (Succ a) where
toInteger _ = toInteger (undefined :: a) + 1
data KDTree a b = -- ...
dimension :: forall a b. MyTypeNat a => KDTree a b -> Integer
dimension = toInteger (undefined :: a)
The downside of an approach like this is of course that you have to write something like KDTree (Succ (Succ (Succ Zero))) Foo instead of KDTree 3 Foo.
sepp2k's answer shows the basic approach to doing this. In fact, a lot of the work has already been done.
Type-level number packages
natural-number and type-level-natural-number
numtype
type-level
Stuff using type-level encodings of natural numbers (examples)
Vec
Dimensional
llvm
ForSyDe
Unfortunately something like this:
data KDTree Int a = ...
isn't really possible. The final type (constructed by KDTree) depends on the value of the Int, which requires a feature called dependent types. Languages like Agda and Epigram support this, but not Haskell.

Resources