在Idris中将字符串转换为整数或自然的最佳方式是什么?
我知道标准库仍然是正在进行的工作,所以如果答案是我应该将它添加到标准库然后那很好我会尝试这样做,但在我认为我会确认之前还没有办法。
如果我想从用户那里阅读索引,我能想到的最好就是这样:
indexAsString <- getLine
let indexAsInt : Integer = cast indexAsString
let items: Vect _ _ = ["shoe", "bat", "hat"]
let i = integerToFin indexAsInt $ length items
maybe (print "invalid index") (\ii => print $ index ii items) i
但是这样,我没有表明失败的迹象。不仅indexAsString可能不是格式允许它转换为Integer这一事实,但最重要的是它在运行时甚至不会失败,因为&#34而产生0 ;糟糕演员&#34; 。
请告诉我有更好的方法和/或指出我正确的方向。
作为旁注,有没有特殊原因在Idris中没有Read类型类?或者它还没有成功呢?
提前谢谢。答案 0 :(得分:6)
Idris在parseInteger
中有一个parsePositive
和Data.String
函数,其类型为签名
Num a => Neg a => String -> Maybe a
和
Num a => String -> Maybe a
http://www.idris-lang.org/docs/current/base_doc/docs/Data.String.html
答案 1 :(得分:4)
我可能会搞错,但我会尝试分享我的想法。 失败的指示是关于解析。
在旧的idris存储库中,我可以看到readInt
String -> Maybe Int
,但我不知道它现在在哪里。
Howerver我找到了here的自定义实现:
charToInt : Char -> Maybe Int
charToInt c = let i = cast {to=Int} c in
let zero = cast {to=Int} '0' in
let nine = cast {to=Int} '9' in
if i < zero || i > nine
then Nothing
else Just (i - zero)
total
parse' : Int -> List Int -> Maybe Int
parse' _ [] = Nothing
parse' acc [d] = Just (10 * acc + d)
parse' acc (d::ds) = parse' (10 * acc + d) ds
total parseInt : String -> Maybe Int
parseInt str = (sequence (map charToInt (unpack str))) >>= parse' 0
main : IO ()
main = do let r = parseInt !getLine
putStrLn "."
它很容易理解它是如何工作的。 charToInt
(可能我认为它可以更好地编码,但我不知道如何)基于cast
,parse
正在逐个递归处理整数{{1}对于List中的每个新整数(例如符号)和*10
映射解包parseInt
和String
并将结果传递给charToInt
。 Haskell中的parse
与!
相似。