Принудительная строгость для списков в haskell

Я сделал очень трудоемкий алгоритм, который в результате выдает короткую строку. Когда я пытаюсь распечатать его (через putStrLn), он появляется на экране посимвольно. Я понял, почему это произошло, и попытался принудительно оценить строку перед фактической печатью.

myPrint !str = putStrLn str

Но это помогает очень мало. Когда я запускал программу в режиме отладки, я заметил, что !str принудительно оценивает только первый символ.

Кто-нибудь знает, почему так и как с этим бороться?


person MaksymB    schedule 05.04.2011    source источник
comment
В чем проблема с печатью посимвольно? Мне нравится такой подход, как видите, когда программа будет оценивать ваши вещи.   -  person fuz    schedule 06.04.2011
comment
Это будет инструмент, просто выглядит немного некрасиво. Но для отладки полностью согласен, может пригодится.   -  person MaksymB    schedule 06.04.2011


Ответы (2)


(!) преобразуется в seq, что оценивается строго как нормальная форма Weak Head, то есть оценивается только как самый внешний конструктор. Для более глубокой оценки вам нужна «глубокая» форма seq.

Это известно как deepseq.

Он находится в пакете deepseq.

person Don Stewart    schedule 05.04.2011
comment
Чтобы уточнить, для списков самым внешним конструктором является самый левый :, что объясняет, почему он принудительно использует только первый символ строки. - person Dan Burton; 06.04.2011
comment
Немного более понятная иллюстрация того, что такое нормальная форма слабой головы, находится здесь - person MaksymB; 07.04.2011

person    schedule
comment
Это будет работать, но только если вам действительно требуется оценка (), например. seq (seqList xs) (doSomethingWith xs). Даже в этом случае будет задействована только корень списка, а не отдельные элементы (не то, чтобы простое принудительное использование корешка бесполезно). Может быть сложно получить правильную строгость! - person John L; 06.04.2011
comment
Кроме того, я думаю, вы имеете в виду seqList в последней строке. - person John L; 06.04.2011
comment
Другой способ — выполнить несколько бесполезных вычислений над списком: length $ filter (==?) list. - person fuz; 06.04.2011