Skip to content

Instantly share code, notes, and snippets.

@marai2
Last active October 28, 2019 18:29
Show Gist options
  • Save marai2/ecb58216e285b077a83a89f7a07e4c41 to your computer and use it in GitHub Desktop.
Save marai2/ecb58216e285b077a83a89f7a07e4c41 to your computer and use it in GitHub Desktop.
How do write this function in idiomatic Haskell?
{--
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