Как да проверя дали Char
в haskell е валидна UTF8 кодова точка?
Имам клас, който генерира низове, предмет на някакъв набор от ограничения, и Arbitrary
екземпляр на този клас (който генерира само низове, които отговарят на тези ограничения). Използвам GenValidity
с това. Но стандартният генератор за String генерира случайни невалидни знаци; като '\xed'
. Не е изненадващо, че това причинява проблеми по-късно.
Под „невалиден“ имам предвид, че Data.Text.Encoding.streamDecodeUtf8
отбелязва грешка:
λ> streamDecodeUtf8 (Data.ByteString.Char8.pack "\xed")
Some "" "\237" _
Бих искал да добавя ограничение към моя екземпляр на GenValidity, което се основава на (хипотетична) isValidUTF8 :: Char -> Bool
функция, но изненадващо не мога да намеря нищо, което да съответства. Най-доброто, което мога да направя, е
((\ (Data.Text.Encoding.Some _ x _) -> x /= "") . Data.Text.Encoding.streamDecodeUtf8With (\ _ _ -> Nothing) . Data.ByteString.Char8.pack) . pure
Което със сигурност е доста тежко и се притеснявам, че преобразуването в ByteString, след това в Text, може да доведе до остри ръбове.
Изненадан съм, че не мога да намеря нищо по-добро/предварително консервирано.
Съвети и насоки са добре дошли!
GHC.Unicode.isPrint $ chr(237)
иputStrLn $ ((chr 237):"")
Разбира се, в началото на забранения диапазон на UnicodeisPrint $ chr 55296
връща False. - person jpmarinier   schedule 13.05.2020'\xed'
е лошо. - person user3416536   schedule 13.05.2020\xed
е непълна последователност. Не можете да генерирате произволна последователност от байтове и да се надявате, че това ще бъде валиден UTF-8 низ. Ако има проблем от страната на производителя, отстраняването на невалидни низове от страна на потребителя може да отнеме цяла вечност; по-добре оправи продуцента. - person n. 1.8e9-where's-my-share m.   schedule 13.05.2020isPrint $ chr (read "0xda65")
връща False, това е в невалидния диапазон D800-DFFF. Може да се наложи да филтрирате продукцията на вашия генератор на ниво Char/String. - person jpmarinier   schedule 13.05.2020