Вы можете использовать safeGetRow :: Matrix a -> Maybe (Vector a)
, который вернет Nothing
в случае, если индекс выходит за пределы диапазона.
Вопрос, конечно, в том, что мы делаем, если индекс выходит за пределы допустимого диапазона. Два разумных варианта:
- используйте
Maybe [Int]
вместо [Int]
в качестве типа возврата и верните Nothing
; или
- возвращает пустой список, поскольку, если узел не находится в матрице смежности, у него нет соседей.
Мы можем, например, реализовать это как:
import Data.Matrix(Matrix, safeGetRow)
import Data.Vector(toList)
neighbours :: AdjacencyMatrix -> Int -> <b>Maybe</b> [Int]
neighbours mat n = map fst . filter snd . zip [0..] . <b>toList</b> <$> safeGetRow n mat
Мы используем toList :: Vector a -> [a]
, чтобы предотвратить использование (!) :: Vector a -> Int -> a
, которое выглядит небезопасным : вы использовали индексы коррекции, но это требует некоторой аргументации, тогда как toList
является полной функцией, и, следовательно, очевидно, всегда будет давать результат.
Мы можем сделать это более компактным, используя findIndices :: (a -> Bool) -> Vector a -> Vector Int
:
import Data.Matrix(Matrix, safeGetRow)
import Data.Vector(<b>findIndices</b>, toList)
neighbours :: AdjacencyMatrix -> Int -> Maybe [Int]
neighbours mat n = toList . <b>findIndices id</b> <$> safeGetRow n mat
Или мы можем использовать maybe :: b -> (a -> b) -> Maybe a -> b
, чтобы использовать вместо него пустой список:
import Data.Matrix(Matrix, safeGetRow)
import Data.Maybe(<b>maybe</b>)
import Data.Vector(findIndices, toList)
neighbours :: AdjacencyMatrix -> Int -> <b>[Int]</b>
neighbours mat n = <b>maybe</b> [] (toList . findIndices id) (safeGetRow n mat)