Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Monad instance of a number-parameterised vector?

Statically sized vectors in Haskell are shown in Oleg Kiselyov's Number-parameterized types and can also be found in the Data.Param.FSVec type from the parameterized-data module on Hackage:

data Nat s => FSVec s a

FSVec is not an instance of the Monad type class.

The monad instance for lists, can be used to remove or duplicate elements:

Prelude> [1,2,3] >>= \i -> case i of 1 -> [1,1]; 2 -> []; _ -> [i]
[1,1,3]

Whether similar to the list version or not, is it possible to construct a monad from a fixed length vector?

like image 876
user2023370 Avatar asked Apr 27 '11 10:04

user2023370


2 Answers

Yes it is possible, if not natural.

The monad has to 'diagonalize' the result in order to satisfy the monad laws.

That is to say, you can look at a vector as a tabulated function from [0..n-1] -> a and then adapt the monad instance for functions.

The resulting join operation takes a square matrix in the form of a vector of vectors and returns its diagonal.

Given

tabulate :: Pos n => (forall m. (Nat m, m :<: n) => m -> a) -> FSVec n a

then

instance Pos n => Monad (FSVec n) where
     return = copy (toNum undefined)
     v >>= f = tabulate (\i -> f (v ! i) ! i)

Sadly uses of this monad are somewhat limited.

I have a half-dozen variations on the theme in my streams package and Jeremy Gibbons wrote a blog post on this monad.

Equivalently, you can view a FSVec n as a representable functor with its representation being natural numbers bounded by n, then use the definitions of bindRep and pureRep in my representable-functors package to get the definition automatically.

like image 145
Edward Kmett Avatar answered Oct 18 '22 10:10

Edward Kmett


That seems impossible given that any monad has a join function. If the vector size is not exactly zero or one this would change the vector size. You can make it a Functor and Applicative, though.

like image 41
augustss Avatar answered Oct 18 '22 12:10

augustss