Haskell создает список из данных нового типа

Это домашнее задание в первую очередь. Нам дана матрица нового типа, которая является реализацией профессором абстрактной матрицы. Моя главная проблема заключается в том, как создать список типа Matrix. Первая функция fillWith, которую мне нужно реализовать, принимает кортеж, который представляет собой (количество строк, количество столбцов) матрицы для создания и данных для размещения в каждом индексе.

module Matrix (Matrix, fillWith, fromRule, numRows, numColumns, 
           at, mtranspose, mmap, add, mult) 
where

-- newtype is like "data", but has some efficiency advantages
newtype Matrix a = Mat ((Int,Int),(Int,Int) -> a)

--fillWith   :: (Int,Int) -> a -> (Matrix a)
--fillWith ix val = Mat ((, 


--trying to create a row of type Matrix
row_matrix :: [a] -> Matrix a
row_matrix ls = Mat ((1, length ls), (\x y -> if x > 1 then undefined else ls !! (y-1)))

person Sammyr93    schedule 08.10.2015    source источник
comment
Это определение Matrix ужасно. Вы можете передать своему профессору, что я так сказал. Unidiomatic, и я оспариваю заявления о выигрыше в эффективности по сравнению с просто немного странным data Matrix a = Mat { width, height :: Int, members :: (Int, Int) -> a }.   -  person Daniel Wagner    schedule 09.10.2015
comment
Возможно, вы захотите задать вопрос об этом новом типе и утверждении данных с конкретным определением.   -  person Franky    schedule 09.10.2015


Ответы (1)


Вам просто не хватает скобок и запятой:

row_matrix ls = Mat ((1, length ls), (\(x,y) -> if x > 1 then undefined else ls !! (y-1)))
                                       ^-^-^--- add these

Mat — это кортеж, в котором:

  • первый элемент сам является кортежем, и
  • второй элемент — это функция, переводящая tuple в значение типа a

Вы всегда можете использовать предложение where или let для упрощения построения значений, например:

row_matrix as = Mat (bounds, accessor)
  where bounds = (1, length as)
        accessor (i,j) = if i > 1 then undefined else as !! (j-1)

Использование предложения where делает код более читабельным.

Чтобы реализовать fillWith, я бы следовал тому же рецепту:

fillWith bounds val = Mat (bounds, accessor)
  where accessor (i,j) = ???

Я думаю, теперь очевидно, что за ??? должно быть.

person ErikR    schedule 08.10.2015
comment
в основном, но проверьте свой ответ с помощью компилятора; есть много способов написать это, например. accessor (i,j) = val или accessor = \(i,j) -> val или accessor = const val - person ErikR; 09.10.2015