Haskell converting between vector types - haskell

I'm starting to learn Haskell, but I'm finding it hard to figure out the small, little things that the tutorials jumps over. Right now I'm working with tuples in the form of Vector.Fixed:
import qualified Data.Vector.Fixed as VF
import qualified Data.Vector.Fixed.Unboxed (Vec 2)
import qualified Data.Vector.Unboxed as VU
let a = VF.mk2 7 7 :: (Int, Int)
let b = VF.mk2 7 7 :: (Vec2 Int)
What's difference between a and b?
How can I make a VF vector f equivalent of
[a, a] = [(7,7), (7,7)]?
How can I make a VU vector g equivalent of [[a], [a,a]] = [[(7,7)], [(7,7), (7,7)]]?
For question 2 and 3, I can't get past the type errors when trying to use the convert function.
I know that my tuples always will be of length 2, but I need a list
(or whatever) f of tuples that can be fixed size, and another g
that is two-dimensional (e.g. [[(1,2),(3,4)],[(1,2)]] where
neither the top list nor the sub lists can be of fixed size. Should
I stick to the same type for f and g?
Data.Vector.Fixed and Data.Vector.Unboxed both seem to come from the
same package, but they have different maintainers. Are they both
official, so to speak, or do they not share any similarities other
than that they both are vector implementations?

Related

Is there an inplace map function for mutable vectors?

If I have a mutable vector (with type IOVector a for example), is there a map-like function that can modify the elements in place?
The vector package provides the modify function but this is only one element at a time. Should I use this or is there a preferred method?
And to clarify, the type of the vector will be the same before and after.
Yep, use modify if you want to modify elements in place. If you find yourself often modifying everything in place, you can define mapModify as follows.
import Data.Foldable (for_)
import qualified Data.Vector.Mutable as MV
mapModify :: (a -> a) -> IOVector a -> IO ()
mapModify f v = for_ [0 .. MV.length v - 1)] (MV.modify v f)
That said, constantly modifying all elements in a vector sounds like you may be better off using immutable vectors and mapping over them using the regular fmap. If that code ends up fusing properly, the intermediate vectors will never even be materialized.

How to count the length of a tuple in Haskell?

I tried searching in web and stackexchange, but surprisingly no one asked how to calculate length of a tuple in Haskell in the form below.
So suppose you have tuple like (1,2,3,4) or (1,3,5,6,7) in Haskell and wish to write the length function that calculates length of a tuple. How can I do this? For list I know how I will be able to do so using recursion without explicitly invoking built-in functions. But tuple is different, and I can't use "head"-"tail" distinction.
Will the method involve creating a new data type?
The reason you don't find anything on this is that it doesn't make a lot of sense to count the length of a tuple:
It is pre-determined a compile time (i.e. you might just as well hard-code it)
There's not really much you could do with that information: unlike with e.g. a list, it's not possible to index specific entries in a generic tuple.
That said, it is possible to achieve your goal, however this shouldn't be a normal function but a type-level function, aka type family. Using singleton type nats:
{-# LANGUAGE TypeFamilies, DataKinds #-}
import Data.Singletons
import Data.Singletons.TypeLits
type family TupLength a :: Nat where
TupLength () = 0
TupLength (a,b) = 2
TupLength (a,b,c) = 3
TupLength (a,b,c,d) = 4
-- ...
TupLength x = 1
Then
> mapM_ print [ natVal (sing :: SNat (TupLength ()))
, natVal (sing :: SNat (TupLength (Int,String,Double)))
, natVal (sing :: SNat (TupLength Bool)) ]
0
3
1
One possible answer (using just the base library) is
import Data.Data
import Data.Functor.Const
length :: Data a => a -> Int
length =
getConst .
gfoldl (\(Const c) _ -> Const (c+1)) (const 0)
I gave a whole talk on this subject at London Haskell recently. The slides are here, but the video has not been published yet.

How to use Linear.V to write static type checked matrix operations (Haskell)?

I'm interested in using Linear.V from the Linear library to write matrix operations on sizes that are known at compile time. However, I'm not sure how to use this library. Where can I find more references on how to use it?
This is a little tricky to ask without a bit more knowledge of what exactly you want to do, but I'll take a stab. Linear.V gives you n-dimensional vectors for any n. In linear, matrices are defined as vectors-of-vectors - Linear.Matrix defines the operations on such values. Linear.Matrix works over various sizes of matrix by being parameterized over two functors, and Linear.V is indeed a Functor so we're good to use those operations.
The following boring example shows how you could work with Linear.V:
{-# LANGUAGE DataKinds #-}
import Linear
import Linear.V
import Data.Vector
identity :: V 2 (V 2 Float)
identity = V (fromList [ V (fromList [1, 0]), V (fromList [0, 1]) ])
calculation :: V 2 (V 2 Float)
calculation = identity !*! identity
It's boring in that it just calculates the product of two identity matrices, but it should give you an idea how to put these pieces together. I'm using GHC 7.6+ type literals to specify that identity is a 2x2 matrix.
Note that using the V constructor is somewhat dangerous - it allows you to "lie" about the size of the vector. For example, if you do the following:
identity :: V 2 (V 2 Float)
identity = V (fromList [ V (fromList [1, 0]) ])
things are likely to go very wrong. It's safer to use fromVector, or perhaps tabulate (tabulate uses the representation of V - which is basically a function from element index to its value).

Set operators not provided by Data.Vector of Haskell, what is the reason

My application involves heavy array operations (e.g. log(1) indexing), thus Data.Vector and Data.Vector.Unboxed are preferred to Data.List.
It also involves many set operations (e.g. intersectBy), which however, are not provided by the Data.Vector.
Each of these functions can be implemented like in Data.List in 3-4 lines .
Is there any reason they all not implemented with Data.Vector? I can only speculate. Maybe set operations in Data.Vector is discouraged for performance reasons, i.e. intersectBy would first produce the intersection through list comprehension and then convert the list into a Data.Vector?
I assume it's missing because intersection of unsorted, immutable arrays must have a worst-case run time of Ω(n*m) without using additional space and Data.Vector is optimized for performance. If you want, you can write that function yourself, though:
import Data.Vector as V
intersect :: Eq a => V.Vector a -> V.Vector a -> V.Vector a
intersect x = V.filter (`V.elem` x)
Or by using a temporary set data structure to achieve an expected O(n + m) complexity:
import Data.HashSet as HS
intersect :: (Hashable a, Eq a) => V.Vector a -> V.Vector a -> V.Vector a
intersect x = V.filter (`HS.member` set)
where set = HS.fromList $ V.toList x
If you can afford the extra memory usage, maybe you can use some kind of aggregate type for your data, for example an array for fast random access and a hash trie like Data.HashSet for fast membership checks and always keep both containers up to date. That way you can reduce the asymptotic complexity for intersection to something like O(min(n, m))

Good functions and techniques for dealing with haskell tuples?

I've been doing a lot of work with tuples and lists of tuples recently and I've been wondering if I'm being sensible.
Things feel awkward and clunky which for me signals that I'm doing something wrong.
For example I've written three convenience functions for getting the first, second and third value in a tuple of 3 values.
Is there a better way I'm missing?
Are there more general functions that allow you to compose and manipulate tuple data?
Here are some things I am trying to do that feel should be generalisable.
Extracting values:
Do I need to create a version of fst,snd,etc... for tuples of size two, three, four and five, etc...?
fst3(x,_,_) = x
fst4(x,_,_,_) = x
Manipulating values:
Can you increment the last value of every tuple in a list of pairs and then use that same function to increment the last value of every tuple in a list of triples?
Zipping and Unzipping values:
There is a zip and a zip3. Do I also need a zip4? or is there some way of creating a general zip function?
Sorry if this seems subjective, I honestly don't know if this is even possible or if I'm wasting my time writing 3 extra functions every time I need a general solution.
Thank you for any help you can give!
Extracting values
Yes, you need to write fstN yourself. But why not extract it in pattern matching?
Zipping and Unzipping values
Data.List already provides up to zip7. For general zipN, use a ZipList.
See How to zip multiple lists in Haskell?.
Manipulating values
Not without extensions. Since all tuples are of different types, you have to create a type class, for example:
{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, FunctionalDependencies #-}
class Firstable a b c | a -> b, a -> c where
firstOf :: a -> b
restOf :: a -> c
concatenate :: b -> c -> a
instance Firstable [a] a [a] where
firstOf = head
restOf = tail
concatenate = (:)
instance Firstable (a,b) a b where
firstOf = fst
restOf = snd
concatenate = (,)
instance Firstable (a,b,c) a (b,c) where
firstOf (x,_,_) = x
restOf (_,x,y) = (x,y)
concatenate x (y,z) = (x,y,z)
instance Firstable (a,b,c,d) a (b,c,d) where
firstOf (x,_,_,_) = x
restOf (_,x,y,z) = (x,y,z)
concatenate x (y,z,w) = (x,y,z,w)
instance Firstable (a,b,c,d,e) a (b,c,d,e) where
firstOf (x,_,_,_,_) = x
restOf (_,x,y,z,w) = (x,y,z,w)
concatenate x (y,z,w,t) = (x,y,z,w,t)
Then you could use
incFirst :: (Num b, Firstable a b c) => a -> a
incFirst x = (1 + firstOf x) `concatenate` restOf x
main = do
print $ map incFirst [(1,2),(3,4),(5,6)]
print $ map incFirst [(1,3,6,7),(2,5,-2,4)]
(lastOf is similar.)
But why not use separate functions?
When I start to have big tuples, I use Haskell's pitiful excuse for record syntax to give each element a name, e.g.,
data LatticeOperations a = LO { bot :: a
, top :: a
, glb :: a
, lub :: a
, le :: a
}
This is a five-tuple, but the names turn into functions that select the individual elements.
For changing tuples, you have record-update syntax. In the example I've just given, it makes no sense to replace just one element, but I might, for example, refine the partial order and replace three elements
lattice { le = le', glb = glb', lub = lub' }
And of course if you have a big record and are just trying to increment you can do something like
data FatRecord = FR { count :: Int, ... }
fat = fat { count = count fat + 1 }
I don't think record syntax helps with zip and unzip.
Once tuples get more than size 3 or so, and/or the same tuple type gets used widely, it's best to use a record.
There is no way to generalise over tuple-size without using extensions like Template Haskell. So if we just consider plain haskell: Yes, you do need to write versions of fst etc. for each tuple-size and no, you can't write a general zip method.
I recently found that
{-# LANGUAGE RecordWildCards #-}
allows for a record to use the field selectors as values -
like this:
data R = R {a::Int, b::String, c::Bool}
testA R{..} = a > 0
or
.. = R {..} where a = 7; b= "x"; c= True
check the GHC manual!
Better late than never: try the Tuple package.
Haskell's built-in fst and snd only support tuple pairs, so you're right to define your own. If you want to increment the last value in a list, reverse the list, work from that end, and reverse it back. If you want that increment to work for lists and lists of tuples, just define a new function that increments for those data types and call that within your increment function for the list. #KennyTM has answered the zipN question.
Working with lists and tuples in Haskell is a little different than a lot of languages, but after a while of they feel especially natural and powerful in comparison.

Resources