Created
July 12, 2017 07:10
-
-
Save rewinfrey/261aceacd47d5e3e42ffcb31d3965935 to your computer and use it in GitHub Desktop.
What do you do when you have a Thing but no db id?
This file contains hidden or 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
#!/usr/bin/env stack | |
-- stack script --resolver lts-8.12 | |
{-# LANGUAGE OverloadedStrings #-} | |
import Data.Text | |
import System.Random | |
data Thing = Thing { id :: Int, name :: Text } deriving Show | |
main :: IO () | |
main = do | |
let thing1 = flip Thing "Pauly Shore" | |
let thing2 = flip Thing "Terry Kiser" | |
print =<< save thing1 | |
print =<< save thing2 | |
let thing1' = Thing' "Jason Silverman" | |
let thing2' = Thing' "Jason Bateman" | |
print =<< save' thing1' | |
print =<< save' thing2' | |
{- | |
Since all things in Haskell are functions (big stretch here), we can represent our Thing without | |
an id as a partially applied function. Not useful, but including it to illustrate the problem. | |
Type aliases can be useful in this context because we can give our partially applied function | |
a type. Unfortunately this limits access to the data inside the UnsavedThing, making this approach | |
problematic for anything practical (like saving that data in the db). | |
-} | |
type UnsavedThing = (Int -> Thing) | |
save :: UnsavedThing -> IO Thing | |
save unsavedThing = do | |
id' <- saveOperation unsavedThing | |
pure $ unsavedThing id' | |
-- Problem: How can I extract the data to save from a partially applied function? | |
where saveOperation unsavedThing = randomIO | |
{- | |
To work around this, you could construct pairs of ids and Things and use a convenience Type alias. | |
This is a zero abstraction approximation of what Persistent is doing but without the overhead of TemplateHaskell. | |
-} | |
data Thing' = Thing' { name' :: Text } deriving Show | |
type IdThing' = (Int, Thing') | |
save' :: Thing' -> IO IdThing' | |
save' thing = do | |
id' <- saveOperation thing | |
pure (id', thing) | |
where saveOperation thing = const randomIO thing |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment