###
Fold a `String`

into an `Int`

type

While working my way through (Sullivan, Goerzen & Stewart, 2009), I came across the problem of converting a

Finally, I came up with the following (unsafe) solution using

This being said, I did find a solution online by Ben Doerr that appears to be quite a little bit simpler. His solution also does not make use of any recursion, likely due to his initial element being

Of course, one of the simplest approaches I've come across is

And because no post is complete without a little Python script, here's an implementation using the same concept I used above in Haskell with fn.py.

References

O'Sullivan, B., Goerzen, J., & Stewart, D. (2009).

`String`

to an `Int`

using folds. This isn't that difficult a problem, but because I'm still a beginner to Haskell, I had to think about it for a few days.Finally, I came up with the following (unsafe) solution using

`foldl`

.import Data.Char (digitToInt) asInt :: String -> Int asInt [] = 0 asInt (x:xs) | x == '-' = (-1) * asInt xs | otherwise = sum $ foldl helper [] $ zip (reverse [0..(length (x:xs) - 1)]) (x:xs) where helper :: [Int] -> (Int,Char) -> [Int] helper totalList (order,digit) = digitToInt digit * 10 ^ order : totalListI separated the state of summing from the rest of the problem, using the fold to 'loop' over the list and raise each digit to the appropriate magnitude based on its position, just as one would in an imperative language. Thus, I believe this is a hybrid solution that uses both recursion and a fold (because of the way I've written my

`helper`

function).`foldl`

is of course not the most memory-efficient implementation, again according to the same chapter in (Sullivan et al., 2009). But because the maximum number of digits we may have in this type is 9 (it ranges from \([-2^{29},2^{29}-1]\)), I don't think lazy evaluation becomes an issue unless you're performing this operation many times, or in large numbers at the same time.This being said, I did find a solution online by Ben Doerr that appears to be quite a little bit simpler. His solution also does not make use of any recursion, likely due to his initial element being

`0`

instead of the empty list as I've used.Of course, one of the simplest approaches I've come across is

`read someString :: Int`

.And because no post is complete without a little Python script, here's an implementation using the same concept I used above in Haskell with fn.py.

#! /usr/bin/env python3.6 # -*- coding: utf-8 -*- # vim:fenc=utf-8 from typing import Text, Callable, List, Tuple from fn.op import foldl Char = Text def asInt(string: str) -> int: """ Convert a str to an int. """ if string[0] == '-': return -asInt(string[1:]) def digitToInt(c: Char) -> int: assert len(c) == 1 return int(c) def helper(totalList: List[int], tup: Tuple[int, Char]) -> List[int]: order, digit = tup value = digitToInt(digit) * 10 ** order totalList.append(value) return totalList indexes = reversed(range(len(string))) return sum(foldl(helper, [])(zip(indexes, string))) if __name__ == '__main__': integer = asInt("54321") print(integer) # 54321 print(type(integer)) #It's easiest to understand how this works if you add a

`print(totalList)`

command before `return`

in `helper`

, which prints the following.[50000] [50000, 4000] [50000, 4000, 300] [50000, 4000, 300, 20] [50000, 4000, 300, 20, 1]which is then of course summed and returned.

References

O'Sullivan, B., Goerzen, J., & Stewart, D. (2009).

*Real World Haskell*. Sebastopol, CA: O'Reilly.