Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The best way to convert a String to an Integer or Natural in Idris

What is the best way to convert a String to an Integer or Natural in Idris?

I know the standard library is still a work in progress and so if the answer is I should add it to the standard library then that's fine I will try and do that, but before I thought I would confirm there isn't already a way.

The best I could come up with is this if I want to read an Index from the user:

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

But this way, I get no indication of failure from cast. Not only is the fact that indexAsString might not be in format allowing it to be converted to an Integer, but on top of that it doesn't even fail at runtime, producing 0 as a result of a "bad cast".

Please tell me there is a better way and/or point me in the right direction.

As a side note, is there a particular reason there is no Read typeclass in Idris? Or has it just not made it in yet?

Thx in advance.

like image 534
jedesah Avatar asked Mar 18 '14 04:03

jedesah


People also ask

Which method accepts a string and converts it into integer?

The method generally used to convert String to Integer in Java is parseInt() of String class.

How do you convert a string to an integer in Python?

To convert, or cast, a string to an integer in Python, you use the int() built-in function. The function takes in as a parameter the initial string you want to convert, and returns the integer equivalent of the value you passed. The general syntax looks something like this: int("str") .

What are the possible ways to convert the string to a number?

You convert a string to a number by calling the Parse or TryParse method found on numeric types ( int , long , double , and so on), or by using methods in the System. Convert class. It's slightly more efficient and straightforward to call a TryParse method (for example, int.


2 Answers

Idris has a parseInteger and parsePositive function in Data.String with the type signatures

Num a => Neg a => String -> Maybe a

and

Num a => String -> Maybe a

http://www.idris-lang.org/docs/current/base_doc/docs/Data.String.html

like image 150
Cameron Martin Avatar answered Sep 22 '22 12:09

Cameron Martin


I may mistake but I try to share what I think about it. indication of failure is about parsing.

In old idris repository I can see readInt which is String -> Maybe Int but I don't know where is it now.

Howerver there is custom implementation I found 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 "."

It's easy to read how does it work. charToInt (probably I think it could be coded better but I don't know how) is based on cast , parse is processing Integers one by one recursive doing *10 for each new Integer from List (e.g. symbol) and parseInt maps unpacked String with charToInt and getting the result passing it to parse. ! is alike =<< in Haskell.

like image 38
cnd Avatar answered Sep 23 '22 12:09

cnd