Last active
October 28, 2019 18:29
-
-
Save marai2/ecb58216e285b077a83a89f7a07e4c41 to your computer and use it in GitHub Desktop.
How do write this function in idiomatic Haskell?
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-- | |
This is more or less a literal translation of a ReasonML function into Haskell. | |
(From the book Web Development with ReasonML.) | |
What would be the idiomatic way to write this in Haskell? | |
I'm having trouble making the function "calc" readable in Haskell | |
as I can't get the binding prioritization of <*> and >>= right. | |
Basically the point of this function in the book is to show | |
how you don't have to write lots of nesting if/elses by using fmap and flatMap. | |
--} | |
import Text.Read (readMaybe) | |
import Data.Decimal | |
(|>) :: a -> (a -> b) -> b | |
x |> f = f x | |
toDouble :: String -> Maybe Double | |
toDouble = readMaybe | |
reciprocal :: Double -> Maybe Double | |
reciprocal x = if x == 0 | |
then Nothing | |
else Just (1 / x) | |
cube :: Double -> Double | |
cube x = x ^ 3 | |
digits :: Int -> Double -> Double | |
digits n d = fromInteger (round (d * 10^n)) / 10^n | |
report :: Maybe Double -> String | |
report Nothing = "Could not calculate result" | |
report (Just d) = "The result is " ++ show d | |
-- This is the function I need help with. | |
calc :: String -> String | |
calc str = str | |
|> toDouble | |
|> (>>= reciprocal) | |
|> fmap cube | |
|> fmap (digits 2) | |
|> report | |
main :: IO () | |
main = do | |
print $ calc "0.25" | |
-- "The result is 64.0" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment