Skip to content

Instantly share code, notes, and snippets.

@joe-warren
Created April 3, 2023 16:44
Show Gist options
  • Select an option

  • Save joe-warren/a60d6f72e7e371f0c38c3a7b5f07ddb5 to your computer and use it in GitHub Desktop.

Select an option

Save joe-warren/a60d6f72e7e371f0c38c3a7b5f07ddb5 to your computer and use it in GitHub Desktop.
{-# Language FlexibleInstances #-}
module SillyVersion where
import Data.Ratio
data SillyVersion = SillyVersion Integer Integer Integer
display :: (() -> SillyVersion) -> String
display f = let SillyVersion maj min pat = f ()
in show maj <> "." <> show min <> "." <> show pat
data Patch = Patch Integer
version :: (Patch -> SillyVersion) -> (Patch -> SillyVersion)
version = id
instance Num (Patch -> SillyVersion) where
(+) = undefined
(-) = undefined
(*) = undefined
negate = id
abs = id
signum = id
fromInteger = undefined
instance Fractional (Patch -> SillyVersion) where
fromRational r (Patch p) =
let num = numerator r
den = denominator r
(maj, rest) = num `quotRem` den
go :: Integer -> Integer
go 0 = 0
go x = let (d, next) = (10 * x) `quotRem` den
in d * 10 + go next
min = go rest `div` 10
in SillyVersion maj min p
(/) = undefined
recip = undefined
instance Num (()-> Patch) where
(+) = undefined
(-) = undefined
(*) = undefined
negate = id
abs = id
signum = id
fromInteger = const . Patch . fromInteger
example :: String
example = display $ version 3.4.21
-- Unfortunately, there's no way to make this work when the minor version has trailing 0s
-- eg, this is "3.1.21
brokenExample = display $ version 3.100.21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment