writing a function that accepts multiple input and has multiple outputs in haskell - 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.

Related

Matrix dimensionality checks at compile time

I was wondering whether is was possible to use the matrix type from Data.Matrix to construct another type with which it becomes possible to perform dimensionality checking at compile time.
E.g. I want to be able to write a function like:
mmult :: Matrix' r c -> Matrix' c r -> Matrix' r r
mmult = ...
However, I don't see how to do this since the arguments to a type constructor Matrix' would have to be types and not integer constants.
I don't see how to do this since the arguments to a type constructor Matrix' would have to be types and not integer constants
They do need to be type-level values, but not necessarily types. “Type-level” basically just means known at compile-time, but this also contains stuff that isn't really types. Types are in particular the type-level values of kind Type, but you can also have type-level strings or, indeed, natural numbers.
{-# LANGUAGE DataKinds, KindSignatures #-}
import GHC.TypeLits
import Data.Matrix
newtype Matrix' (n :: Nat) (m :: Nat) a
= StaMat {getStaticSizeMatrix :: Matrix a}
mmult :: Num a => Matrix' n m a -> Matrix' l n a -> Matrix' l m a
mmult (StaMat f) (StaMat g) = StaMat $ multStd f g
I would remark that matrices are only a special case of a much more general mathematical concept, that of linear maps between vector spaces. And since vector spaces can be seen as particular types, it actually makes a lot of sense to not use mere integers as the type-level tags, but the actual spaces. What you have then is a category, and it allows you to deal with both dynamic- and static size matrix/vector types, and can even be generalised to completely different spaces like infinite-dimensional Hilbert spaces.
{-# LANGUAGE GADTs #-}
newtype StaVect (n :: Nat) a
= StaVect {getStaticSizeVect :: Vector a}
data LinMap v w where
StaMat :: Matrix a -> LinMap (StaVec n a) (StaVec m a)
-- ...Add more constructors for mappings between other sorts of vector spaces...
linCompo :: LinMap v w -> LinMap u v -> LinMap u w
linCompo (StaMat f) (StaMat g) = StaMat $ multStd f g
The linearmap-category package pursues this direction.

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?

Haskell: function that takes a type argument and returns a value depending on that type?

The question is basically: how do I write a function f in Haskell that takes a value x and a type argument T, and then returns a value y = f x T which depends both on x and T, without explicitly ascribing the type of the entire expression f x T? (The f x T is not valid Haskell, but a placeholder-pseudo-syntax).
Consider the following situation. Suppose that I have a typeclass Transform a b which provides a single function transform :: a -> b. Suppose that I also have a bunch of instances of Transform for various combinations of types a b. Now I'd like to chain multiple transform-functions together. However, I want the Transform-instance to be selected depending on the previosly constructed chain and on the next type in the chain of transformations. Ideally, this would give me something like this (with hypothetical functions source and migrate and invalid syntax << >> for "passing type parameters"; migrate is used as infix-operation):
z = source<<A>> migrate <<B>> ... migrate <<Z>>
Here, source somehow generates values of type A, and each migrate<<T>> is supposed to find an instance Transform S T and append it to the chain.
What I came up with so far: It actually (almost) works in Haskell using type ascriptions. Consider the following (compilable) example:
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE ExistentialQuantification #-}
-- compiles with:
-- The Glorious Glasgow Haskell Compilation System, version 8.2.2
-- A typeclass with two type-arguments
class Transform a b where
transform :: a -> b
-- instances of `T` forming a "diamond"
--
-- String
-- / \
-- / \
-- / \
-- / \
-- Double Rational
-- \ /
-- \ /
-- \ /
-- \ /
-- Int
--
instance Transform String Double where
transform = read
instance Transform String Rational where
transform = read -- turns out to be same as fo `Double`, but pretend it's different
instance Transform Double Int where
transform = round
instance Transform Rational Int where
transform = round -- pretend it's different from `Double`-version
-- A `MigrationPath` to `b` is
-- essentially some data source and
-- a chain of transformations
-- supplied by typeclass `T`
--
-- The `String` here is a dummy for a more
-- complex operation that is roughly `a -> b`
data MigrationPath b = Source b
| forall a . Modify (MigrationPath a) (a -> b)
-- A function that appends a transformation `T` from `a` to `b`
-- to a `MigrationPath a`
migrate :: Transform a b => MigrationPath a -> MigrationPath b
migrate mpa = Modify mpa transform
-- Build two paths along the left and right side
-- of the diamond
leftPath :: MigrationPath Int
leftPath = migrate ((migrate ((Source "3.333") :: (MigrationPath String))) :: (MigrationPath Double))
rightPath :: MigrationPath Int
rightPath = migrate((migrate ((Source "10/3") :: (MigrationPath String))) :: (MigrationPath Rational))
main = putStrLn "it compiles, ship it"
In this example, we define Transform instances such that they form two possible MigrationPaths from String to Int. Now, we (as a human beings) want to exercise our free will, and force the compiler to pick either the left path, or the right path in this chain of transformations.
This is even kind-of possible in this case. We can force the compiler to create the right chain by constructing an "onion" of constraints from type ascriptions:
leftPath :: MigrationPath Int
leftPath = migrate ((migrate ((Source "3.333") :: (MigrationPath String))) :: (MigrationPath Double))
However, I find it very sub-optimal for two reasons:
The AST (migrate ... (Type)) grows to both sides around the Source (this is a minor issue, it probably can be rectified using infix operators with left-associativity).
More severe: if the type of MigrationPath stored not only the target type, but also the source type, with the type-ascription approach we would have to repeat every type in the chain twice, which would make the entire approach too awkward to use.
Question: is there any way to construct the above chain of transformations in such a way that only "the next type", and not the entire "type of the MigrationPath T" has to be ascribed?
What I'm not asking: It is clear to me that in the above toy-example, it would be easier to define functions transformStringToInt :: String -> Int etc, and then just chain them together using .. This is not the question. The question is: how do I force the compiler to generate the expressions corresponding to transformStringToInt when I specify just the type. In the actual application, I want to specify only the types, and use a set of rather complicated rules to derive an appropriate instance with the right transform-function.
(Optional): Just to give an impression of what I'm looking for. Here is a completely analogous example from Scala:
// typeclass providing a transformation from `X` to `Y`
trait Transform[X, Y] {
def transform(x: X): Y
}
// Some data migration path ending with `X`
sealed trait MigrationPath[X] {
def migrate[Y](implicit t: Transform[X, Y]): MigrationPath[Y] = Migrate(this, t)
}
case class Source[X](x: X) extends MigrationPath[X]
case class Migrate[A, X](a: MigrationPath[A], t: Transform[A, X]) extends MigrationPath[X]
// really bad implementation of fractions
case class Q(num: Int, denom: Int) {
def toInt: Int = num / denom
}
// typeclass instances for various type combinations
implicit object TransformStringDouble extends Transform[String, Double] {
def transform(s: String) = s.toDouble
}
implicit object TransformStringQ extends Transform[String, Q] {
def transform(s: String) = Q(s.split("/")(0).toInt, s.split("/")(1).toInt)
}
implicit object TransformDoubleInt extends Transform[Double, Int] {
def transform(d: Double) = d.toInt
}
implicit object TransformQInt extends Transform[Q, Int] {
def transform(q: Q) = q.toInt
}
// constructing migration paths that yield `Int`
val leftPath = Source("3.33").migrate[Double].migrate[Int]
val rightPath = Source("10/3").migrate[Q].migrate[Int]
Notice how migrate-method requires nothing but the "next type", not the type ascription for the entire expression constructed so far.
Related: I want to note that this question is not an exact duplicate of "Pass Types as arguments to a function in Haskell?". My use case is a bit different. I also tend to disagree with the answers there that "it's not possible / you don't need it", because I actually do have a solution, it's just rather ugly from the purely syntactical point of view.
Use the TypeApplications language extension, which allows you to explicitly instantiate individual type variables. The following code seems to have the flavor you want, and it typechecks:
{-# LANGUAGE ExplicitForAll, FlexibleInstances, MultiParamTypeClasses, TypeApplications #-}
class Transform a b where
transform :: a -> b
instance Transform String Double where
transform = read
instance Transform String Rational where
transform = read
instance Transform Double Int where
transform = round
instance Transform Rational Int where
transform = round
transformTo :: forall b a. Transform a b => a -> b
transformTo = transform
stringToInt1 :: String -> Int
stringToInt1 = transform . transformTo #Double
stringToInt2 :: String -> Int
stringToInt2 = transform . transformTo #Rational
The definition transformTo uses an explicit use of forall to flip b and a so that TypeApplications will instantiate b first.
Use the type applications syntax extension.
> :set -XTypeApplications
> transform #_ #Int (transform #_ #Double "9007199254740993")
9007199254740992
> transform #_ #Int (transform #_ #Rational "9007199254740993%1")
9007199254740993
Inputs carefully chosen to give the lie to your "turns out to be the same as for Double" comment, even after correcting for syntax differences in the input.

What can type families do that multi param type classes and functional dependencies cannot

I have played around with TypeFamilies, FunctionalDependencies, and MultiParamTypeClasses. And it seems to me as though TypeFamilies doesn't add any concrete functionality over the other two. (But not vice versa). But I know type families are pretty well liked so I feel like I am missing something:
"open" relation between types, such as a conversion function, which does not seem possible with TypeFamilies. Done with MultiParamTypeClasses:
class Convert a b where
convert :: a -> b
instance Convert Foo Bar where
convert = foo2Bar
instance Convert Foo Baz where
convert = foo2Baz
instance Convert Bar Baz where
convert = bar2Baz
Surjective relation between types, such as a sort of type safe pseudo-duck typing mechanism, that would normally be done with a standard type family. Done with MultiParamTypeClasses and FunctionalDependencies:
class HasLength a b | a -> b where
getLength :: a -> b
instance HasLength [a] Int where
getLength = length
instance HasLength (Set a) Int where
getLength = S.size
instance HasLength Event DateDiff where
getLength = dateDiff (start event) (end event)
Bijective relation between types, such as for an unboxed container, which could be done through TypeFamilies with a data family, although then you have to declare a new data type for every contained type, such as with a newtype. Either that or with an injective type family, which I think is not available prior to GHC 8. Done with MultiParamTypeClasses and FunctionalDependencies:
class Unboxed a b | a -> b, b -> a where
toList :: a -> [b]
fromList :: [b] -> a
instance Unboxed FooVector Foo where
toList = fooVector2List
fromList = list2FooVector
instance Unboxed BarVector Bar where
toList = barVector2List
fromList = list2BarVector
And lastly a surjective relations between two types and a third type, such as python2 or java style division function, which can be done with TypeFamilies by also using MultiParamTypeClasses. Done with MultiParamTypeClasses and FunctionalDependencies:
class Divide a b c | a b -> c where
divide :: a -> b -> c
instance Divide Int Int Int where
divide = div
instance Divide Int Double Double where
divide = (/) . fromIntegral
instance Divide Double Int Double where
divide = (. fromIntegral) . (/)
instance Divide Double Double Double where
divide = (/)
One other thing I should also add is that it seems like FunctionalDependencies and MultiParamTypeClasses are also quite a bit more concise (for the examples above anyway) as you only have to write the type once, and you don't have to come up with a dummy type name which you then have to type for every instance like you do with TypeFamilies:
instance FooBar LongTypeName LongerTypeName where
FooBarResult LongTypeName LongerTypeName = LongestTypeName
fooBar = someFunction
vs:
instance FooBar LongTypeName LongerTypeName LongestTypeName where
fooBar = someFunction
So unless I am convinced otherwise it really seems like I should just not bother with TypeFamilies and use solely FunctionalDependencies and MultiParamTypeClasses. Because as far as I can tell it will make my code more concise, more consistent (one less extension to care about), and will also give me more flexibility such as with open type relationships or bijective relations (potentially the latter is solver by GHC 8).
Here's an example of where TypeFamilies really shines compared to MultiParamClasses with FunctionalDependencies. In fact, I challenge you to come up with an equivalent MultiParamClasses solution, even one that uses FlexibleInstances, OverlappingInstance, etc.
Consider the problem of type level substitution (I ran across a specific variant of this in Quipper in QData.hs). Essentially what you want to do is recursively substitute one type for another. For example, I want to be able to
substitute Int for Bool in Either [Int] String and get Either [Bool] String,
substitute [Int] for Bool in Either [Int] String and get Either Bool String,
substitute [Int] for [Bool] in Either [Int] String and get Either [Bool] String.
All in all, I want the usual notion of type level substitution. With a closed type family, I can do this for any types (albeit I need an extra line for each higher-kinded type constructor - I stopped at * -> * -> * -> * -> *).
{-# LANGUAGE TypeFamilies #-}
-- Subsitute type `x` for type `y` in type `a`
type family Substitute x y a where
Substitute x y x = y
Substitute x y (k a b c d) = k (Substitute x y a) (Substitute x y b) (Substitute x y c) (Substitute x y d)
Substitute x y (k a b c) = k (Substitute x y a) (Substitute x y b) (Substitute x y c)
Substitute x y (k a b) = k (Substitute x y a) (Substitute x y b)
Substitute x y (k a) = k (Substitute x y a)
Substitute x y a = a
And trying at ghci I get the desired output:
> :t undefined :: Substitute Int Bool (Either [Int] String)
undefined :: Either [Bool] [Char]
> :t undefined :: Substitute [Int] Bool (Either [Int] String)
undefined :: Either Bool [Char]
> :t undefined :: Substitute [Int] [Bool] (Either [Int] String)
undefined :: Either [Bool] [Char]
With that said, maybe you should be asking yourself why am I using MultiParamClasses and not TypeFamilies. Of the examples you gave above, all except Convert translate to type families (albeit you will need an extra line per instance for the type declaration).
Then again, for Convert, I am not convinced it is a good idea to define such a thing. The natural extension to Convert would be instances such as
instance (Convert a b, Convert b c) => Convert a c where
convert = convert . convert
instance Convert a a where
convert = id
which are as unresolvable for GHC as they are elegant to write...
To be clear, I am not saying there are no uses of MultiParamClasses, just that when possible you should be using TypeFamilies - they let you think about type-level functions instead of just relations.
This old HaskellWiki page does an OK job of comparing the two.
EDIT
Some more contrasting and history I stumbled upon from augustss blog
Type families grew out of the need to have type classes with
associated types. The latter is not strictly necessary since it can be
emulated with multi-parameter type classes, but it gives a much nicer
notation in many cases. The same is true for type families; they can
also be emulated by multi-parameter type classes. But MPTC gives a
very logic programming style of doing type computation; whereas type
families (which are just type functions that can pattern match on the
arguments) is like functional programming.
Using closed type families
adds some extra strength that cannot be achieved by type classes. To
get the same power from type classes we would need to add closed type
classes. Which would be quite useful; this is what instance chains
gives you.
Functional dependencies only affect the process of constraint solving, while type families introduced the notion of non-syntactic type equality, represented in GHC's intermediate form by coercions. This means type families interact better with GADTs. See this question for the canonical example of how functional dependencies fail here.

How to have an operator which adds/subtracts both absolute and relative values, in Haskell

(Apologies for the weird title, but I could not think of a better one.)
For a personal Haskell project I want to have the concepts of 'absolute values' (like a frequency) and relative values (like the ratio between two frequencies). In my context, it makes no sense to add two absolute values: one can add relative values to produce new relative values, and add a relative value to an absolute one to produce a new absolute value (and likewise for subtraction).
I've defined type classes for these: see below. However, note that the operators ##+ and #+ have a similar structure (and likewise for ##- and #-). Therefore I would prefer to merge these operators, so that I have a single addition operator, which adds a relative value (and likewise a single subtraction operator, which results in a relative value). UPDATE: To clarify, my goal is to unify my ##+ and #+ into a single operator. My goal is not to unify this with the existing (Num) + operator.
However, I don't see how to do this with type classes.
Question: Can this be done, and if so, how? Or should I not be trying?
The following is what I currently have:
{-# LANGUAGE MultiParamTypeClasses #-}
class Abs a where
nullPoint :: a
class Rel r where
zero :: r
(##+) :: r -> r -> r
neg :: r -> r
(##-) :: Rel r => r -> r -> r
r ##- s = r ##+ neg s
class (Abs a, Rel r) => AbsRel a r where
(#+) :: a -> r -> a
(#-) :: a -> a -> r
I think you're looking for a concept called a Torsor. A torsor consists of set of values, set of differences, and operator which adds a difference to a value. Additionally, the set of differences must form an additive group, so differences also can be added together.
Interestingly, torsors are everywhere. Common examples include
Points and Vectors
Dates and date-differences
Files and diffs
etc.
One possible Haskell definition is:
class Torsor a where
type TorsorOf a :: *
(.-) :: a -> a -> TorsorOf a
(.+) :: a -> TorsorOf a -> a
Here are few example instances:
instance Torsor UTCTime where
type TorsorOf UTCTime = NominalDiffTime
a .- b = diffUTCTime a b
a .+ b = addUTCTime b a
instance Torsor Double where
type TorsorOf Double = Double
a .- b = a - b
a .+ b = a + b
instance Torsor Int where
type TorsorOf Int = Int
a .- b = a - b
a .+ b = a + b
In the last case, notice that the two sets of the torsors don't need to be a different set, which makes adding your relative values together simple.
For more information, see a much nicer description in Roman Cheplyakas blog
I don't think you should be trying to unify these operators. Subtracting two vectors and subtracting two points are fundamentally different operations. The fact that it's difficult to represent them as the same thing in the type system is not the type system being awkward - it's because these two concepts really are different things!
The mathematical framework behind what you're working with is the affine space.
These are already available in Haskell in the vector-space package (do cabal install vector-space at the command prompt). Rather than using multi parameter type classes, they use type families to associate a vector (relative) type with each point (absolute) type.
Here's a minimal example showing how to define your own absolute and relative data types, and their interaction:
{-# LANGUAGE TypeFamilies #-}
import Data.VectorSpace
import Data.AffineSpace
data Point = Point { px :: Float, py :: Float }
data Vec = Vec { vx :: Float, vy :: Float }
instance AdditiveGroup Vec where
zeroV = Vec 0 0
negateV (Vec x y) = Vec (-x) (-y)
Vec x y ^+^ Vec x' y' = Vec (x+x') (y+y')
instance AffineSpace Point where
type Diff Point = Vec
Point x y .-. Point x' y' = Vec (x-x') (y-y')
Point x y .+^ Vec x' y' = Point (x+x') (y+y')
You have two answers telling you what you should do, here's another answer telling you how to do what you asked for (which might not be a good idea). :)
class Add a b c | a b -> c where
(#+) :: a -> b -> c
instance Add AbsTime RelTime AbsTime where
(#+) = ...
instance Add RelTime RelTime RelTime where
(#+) = ...
The overloading for (#+) makes it very flexible. Too flexible, IMO. The only restraint is that the result type is determined by the argument types (without this FD the operator becomes almost unusable because it constrains nothing).

Resources