2014-01-31 4 views
0

Что я хочу сделать, это применить функцию stoline на каждом элементе (String) из списка, переданного stomap ..Haskell - карта ошибки функция возвращает список

Тип stoline: stoline :: String -> [Obj].

Вот мой код:

stomap :: [[String]] -> [Obj] 
stomap [[val]] = stoline val 
stomap (val:vals) = map (\a -> stoline a) val ++ ... 

Пример данных, передаваемых stomap: [["0","133","2"],["6","0","0"],["656","0","3"]].


Ошибка: Не удалась соответствует ожидаемому типу Obj с фактическим типом [Obj] в возвращаемом типе вызова stoline.
Проблема заключается в map функция, которая возвращает список (и не должен!), Но я не знаю, как избежать этой проблемы ..

+1

FYI, '[Obj]' это список, а не массив. Семантика и время доступа разные.Например, списки имеют O (k) доступ к элементу k'th, а массивы имеют O (1) доступ к k-му элементу. – rampion

+0

Спасибо за комментарий, я исправил его (написав ошибку ..); +1! – Val

+1

Ну, по вашему мнению, Stoline берет строку, а не список строк. –

ответ

3

Ваш первый случай не является необходимым, и есть ошибка в вашем втором случае:

map (\a -> stoline a) val ++ ... 

val здесь [String], так map (\a -> stoline a) val является [[Obj]]. Поскольку вы используете ++, чтобы объединить его с остальными результатами, ваш конечный результат будет иметь тип [[Obj]], а не [Obj].

Давайте переделки его:

stomap :: [[String]] -> [Obj] 
stomap lolos = concatMap (\los -> concatMap (\s -> stoline s) los) lolos 

lolos список списков строк, los список строк, и s является строкой.

Мы используем concatMap здесь, а не нормальный map, так как мы хотим, чтобы создать единый список объектов [Obj] не вложенный список списков списков объектов: [[[Obj]]], и так как мы бежим stoline на каждом String в ввода, нам нужно свернуть эту структуру, когда мы пройдем lolos.

Мы можем очистить вышеуказанный код (сделайте его более haskelly), сделав его бесшумным. \s -> stoline s такая же, как stoline, так что мы могли бы:

stomap lolos = concatMap (\los -> concatMap stoline los) lolos 

\los -> concatMap stoline los такая же, как concatMap stoline, так что мы могли бы сократить, что:

stomap lolos = concatMap (concatMap stoline) lolos 

И мы можем опустить аргумент с обеих сторон , давая нам:

stomap = concatMap (concatMap stoline) 

Сначала это может показаться неразборчивым, но для опытного haskell er, это можно прочитать еще более четко, чем ваш исходный код - мне ясно, что эта последняя версия просто объединяет результаты работы stoline над списком списков.

+0

Спасибо за подробный ответ! Это решает мою проблему, и объяснение мне поможет, поэтому ответ, конечно, получится :)! – Val

Смежные вопросы