Skip to content

Commit 6b7bd39

Browse files
committed
added convenience function: mxArrayGetFirst
1 parent b4d46be commit 6b7bd39

File tree

2 files changed

+33
-18
lines changed

2 files changed

+33
-18
lines changed

Foreign/Matlab/Array.hsc

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ module Foreign.Matlab.Array (
3030
mxArrayGet, mxArraySet,
3131
-- | array list access
3232
mxArrayGetList, mxArraySetList,
33-
mxArrayGetAll, mxArraySetAll,
33+
mxArrayGetAll, mxArraySetAll, mxArrayGetFirst,
3434
fromListIO, cellFromListsIO,
3535

3636
-- * Struct access
@@ -71,14 +71,14 @@ type MNullArray = MXArray MNull
7171
-- |Safely cast a generic array to a NULL array, or return Nothing if the array is not NULL
7272
castMNull :: MAnyArray -> MIO (Maybe MNullArray)
7373
castMNull a
74-
| isMNull a = return $ Just (unsafeCastMXArray a)
75-
| otherwise = return Nothing
74+
| isMNull a = pure $ Just (unsafeCastMXArray a)
75+
| otherwise = pure Nothing
7676

7777
foreign import ccall unsafe mxGetClassID :: MXArrayPtr -> IO MXClassID
7878
-- |Return the representation of the type of the elements of an array
7979
mxArrayClass :: MXArray a -> IO MXClass
8080
mxArrayClass a
81-
| isMNull a = return $ MXClassNull
81+
| isMNull a = pure $ MXClassNull
8282
| otherwise = withMXArray a mxGetClassID >.= mx2hs
8383

8484
ndims :: MWSize -> Ptr MWSize -> IO MSize
@@ -114,8 +114,8 @@ mxArrayLength a = ii =.< withMXArray a mxGetNumberOfElements
114114
foreign import ccall unsafe mxCalcSingleSubscript :: MXArrayPtr -> MWSize -> Ptr MWIndex -> IO MWIndex
115115
-- |Convert an array subscript into an offset
116116
mIndexOffset :: MXArray a -> MIndex -> MIO Int
117-
mIndexOffset _ (MSubs []) = return 0
118-
mIndexOffset _ (MSubs [i]) = return i
117+
mIndexOffset _ (MSubs []) = pure 0
118+
mIndexOffset _ (MSubs [i]) = pure i
119119
mIndexOffset a (MSubs i) = ii =.< withMXArray a (withNSubs i . uncurry . mxCalcSingleSubscript)
120120

121121
foreign import ccall unsafe mxDuplicateArray :: MXArrayPtr -> IO MXArrayPtr
@@ -176,7 +176,7 @@ class MXArrayComponent a where
176176
-- |Create a row vector from the given list.
177177
createRowVector :: [a] -> MIO (MXArray a)
178178

179-
isMXArray _ = return False
179+
isMXArray _ = pure False
180180
isMXScalar a = liftM2 (&&) (isMXArray a) (all (1 ==) =.< mxArraySize a)
181181

182182
mxArrayGetOffsetList a o n = mapM (mxArrayGetOffset a) [o..o+n-1]
@@ -187,15 +187,15 @@ class MXArrayComponent a where
187187
createMXScalar x = do
188188
a <- createMXArray [1]
189189
mxArraySetOffset a 0 x
190-
return a
190+
pure a
191191
createRowVector l = do
192192
a <- createMXArray [1,length l]
193193
mxArraySetOffsetList a 0 l
194-
return a
194+
pure a
195195
createColVector l = do
196196
a <- createMXArray [length l]
197197
mxArraySetOffsetList a 0 l
198-
return a
198+
pure a
199199

200200
-- |Get the value of the specified array element. Does not check bounds.
201201
mxArrayGet :: MXArrayComponent a => MXArray a -> MIndex -> MIO a
@@ -210,7 +210,7 @@ mxArraySet a i v = do
210210
mxArrayGetList :: MXArrayComponent a => MXArray a -> MIndex -> Int -> MIO [a]
211211
mxArrayGetList a i n = do
212212
o <- mIndexOffset a i
213-
n <- if n == -1 then subtract o =.< mxArrayLength a else return n
213+
n <- if n == -1 then subtract o =.< mxArrayLength a else pure n
214214
mxArrayGetOffsetList a o n
215215
-- |@'mxArraySetList' a i l@ sets the sequential items in array @a@ starting at index @i@ to @l@. Does not check bounds.
216216
mxArraySetList :: MXArrayComponent a => MXArray a -> MIndex -> [a] -> MIO ()
@@ -226,13 +226,18 @@ mxArrayGetAll a = mxArrayGetList a mStart (-1)
226226
mxArraySetAll :: MXArrayComponent a => MXArray a -> [a] -> IO ()
227227
mxArraySetAll a = mxArraySetList a mStart
228228

229+
mxArrayGetFirst :: MXArrayComponent a => MXArray a -> MIO (Either String a)
230+
mxArrayGetFirst arr
231+
| isMNull arr = pure $ Left "Couldn't get first element of null array"
232+
| otherwise = Right <$> mxArrayGetOffset arr 0
233+
229234
-- |Safely cast a generic array to a type, or return Nothing if the array does not have the proper type
230235
castMXArray :: forall a. MXArrayComponent a => MAnyArray -> MIO (Maybe (MXArray a))
231236
castMXArray a
232-
| isMNull a = return Nothing
237+
| isMNull a = pure Nothing
233238
| otherwise = do
234239
y <- isMXArray b
235-
return $ if y then Just b else Nothing
240+
pure $ if y then Just b else Nothing
236241
where
237242
b :: MXArray a
238243
b = unsafeCastMXArray a
@@ -386,7 +391,8 @@ foreign import ccall unsafe mxSetField :: MXArrayPtr -> MWIndex -> CString -> MX
386391
foreign import ccall unsafe mxGetFieldByNumber :: MXArrayPtr -> MWIndex -> CInt -> IO MXArrayPtr
387392
foreign import ccall unsafe mxSetFieldByNumber :: MXArrayPtr -> MWIndex -> CInt -> MXArrayPtr -> IO ()
388393
389-
-- |Return the contents of the named field for the given element. Returns 'MNullArray' on no such field or if the field itself is NULL
394+
-- |Return the contents of the named field for the given element.
395+
-- |Returns 'MNullArray' on no such field or if the field itself is NULL
390396
mStructGet :: MStructArray -> MIndex -> String -> MIO MAnyArray
391397
-- |Sets the contents of the named field for the given element. The input is stored in the array -- no copy is made.
392398
mStructSet :: MStructArray -> MIndex -> String -> MXArray a -> MIO ()
@@ -435,7 +441,7 @@ instance MXArrayComponent MStruct where
435441
createMXScalar (MStruct fv) = do
436442
a <- createStruct [1] f
437443
withMXArray a $ \a -> zipWithM_ (\i v -> withMXArray v (mxSetFieldByNumber a 0 i)) [0..] v
438-
return a
444+
pure a
439445
where
440446
(f,v) = unzip fv
441447
@@ -446,7 +452,7 @@ mObjectGetClass a = do
446452
b <- boolC =.< withMXArray a mxIsObject
447453
if b
448454
then Just =.< withMXArray a (mxGetClassName >=> peekCString)
449-
else return Nothing
455+
else pure Nothing
450456
451457
foreign import ccall unsafe mxSetClassName :: MXArrayPtr -> CString -> IO CInt
452458
-- |Set classname of an unvalidated object array. It is illegal to call this function on a previously validated object array.
@@ -476,14 +482,14 @@ instance (RealFloat a, MNumeric a, MXArrayData mx a) => MXArrayComponent (MCompl
476482
mxArrayGetOffset a o = do
477483
r <- withRealDataOff a o (mx2hs .=< peek)
478484
c <- withImagDataOff a o (mx2hs .=< peek)
479-
return $ r :+ c
485+
pure $ r :+ c
480486
mxArraySetOffset a o (r :+ c) = do
481487
withRealDataOff a o (\p -> poke p (hs2mx r))
482488
withImagDataOff a o (\p -> poke p (hs2mx c))
483489
mxArrayGetOffsetList a o n = do
484490
r <- withRealDataOff a o (map mx2hs .=< peekArray n)
485491
c <- withImagDataOff a o (map mx2hs .=< peekArray n)
486-
return $ zipWith (:+) r c
492+
pure $ zipWith (:+) r c
487493
mxArraySetOffsetList a o v = do
488494
withRealDataOff a o (\p -> pokeArray p (map hs2mx r))
489495
withImagDataOff a o (\p -> pokeArray p (map hs2mx c))

test/Test/Engine.hs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ runEngineTests host = do
2525
addpath eng testPath
2626
runLocalMatFun eng
2727
cosOfPi eng
28+
testGetFirst eng
2829
testAbstractValueUse eng
2930
testTypedAbstractValueUse eng
3031
testGetByteStreamFromArray eng
@@ -52,6 +53,14 @@ cosBody eng cosFun x = do
5253
y <- mxScalarGet y
5354
print (y :: MDouble)
5455

56+
testGetFirst :: Engine -> IO ()
57+
testGetFirst eng = do
58+
putStrLn $ "\n-- testGetFirst --"
59+
xa <- createMXScalar (1.0 :: MDouble)
60+
xEi <- mxArrayGetFirst xa
61+
let xRes = assert (xEi == Right 1.0) xEi
62+
putStrLn $ " xRes is : " <> (show xRes)
63+
5564
testAbstractValueUse :: Engine -> IO ()
5665
testAbstractValueUse eng = do
5766
putStrLn $ "\n-- testAbstractValueUse --"

0 commit comments

Comments
 (0)