#makeitem
Explore tagged Tumblr posts
Photo
ワクワクお出かけの時のポーチの中身を見せちゃうね😊🌸 #whatsinmypouch #pouch #lemon8 #lemon8厳選クリエイター #disneymarie #ポーチの中身 #makeitem #化粧直しグッズ #マリーポーチ https://www.instagram.com/p/CkieQa6pMS-/?igshid=NGJjMDIxMWI=
0 notes
Text
Expressing relations between types, part 8
So how could it be shorter with a true dependent type language like Idris?
It's good that we no longer need singleton types and convert types and those singleton types and vise versa, but we still need to write a lot even though instances of DecEq and Show might be able to be derived using elaborator reflection.
import Data.List.Elem import Decidable.Equality.Core data Cat = Cat1 | Cat2 cat1NotCat2 : Cat1 = Cat2 -> Void cat1NotCat2 Refl impossible DecEq Cat where decEq Cat1 Cat1 = Yes Refl decEq Cat2 Cat2 = Yes Refl decEq Cat1 Cat2 = No cat1NotCat2 decEq Cat2 Cat1 = No $ negEqSym cat1NotCat2 Show Cat where show Cat1 = "Cat1" show Cat2 = "Cat2" readCat : String -> Maybe Cat readCat "Cat1" = Just Cat1 readCat "Cat2" = Just Cat2 readCat _ = Nothing data SubCat = SubCat1 | SubCat2 | SubCat3 DecEq SubCat where decEq SubCat1 SubCat1 = Yes Refl decEq SubCat2 SubCat2 = Yes Refl decEq SubCat3 SubCat3 = Yes Refl decEq _ _ = No believe_me Show SubCat where show SubCat1 = "SubCat1" show SubCat2 = "SubCat2" show SubCat3 = "SubCat3" readSubCat : String -> Maybe SubCat readSubCat "SubCat1" = Just SubCat1 readSubCat "SubCat2" = Just SubCat2 readSubCat "SubCat3" = Just SubCat3 readSubCat _ = Nothing validSubCats : Cat -> List SubCat validSubCats Cat1 = [SubCat1, SubCat2] validSubCats Cat2 = [SubCat2, SubCat3] data Item: Cat -> SubCat -> Type where MkItem : Elem subCat (validSubCats cat) -> Item cat subCat data SomeItem : Type where MkSomeItem : Item cat subCat -> SomeItem {cat : Cat} -> {subCat : SubCat} -> Show (Item cat subCat) where show (MkItem _) = "Item " ++ show cat ++ " " ++ show subCat buildItem : (cat : Cat) -> (subCat : SubCat) -> Maybe (Item cat subCat) buildItem cat subCat = let elem = isElem subCat (validSubCats cat) in case elem of Yes elem => Just $ MkItem elem No _ => Nothing makeItem : String -> String -> Maybe SomeItem makeItem cat subCat = do cat <- readCat cat subCat <- readSubCat subCat MkSomeItem <$> buildItem cat subCat
0 notes
Text
Expressing relations between types, part 1
Let's consider the situation where you have an item that has a category and a sub category. You can express this idea like this.
module Item ( Item , cat , subCat , Cat(..) , SubCat(..) , buildItem , makeItem ) where import Control.Monad (join) import Text.Read (readMaybe) data Cat = Cat1 | Cat2 deriving (Show, Read, Eq) data SubCat = SubCat1 | SubCat2 | SubCat3 deriving (Show, Read, Eq) data Item = Item { cat :: Cat , subCat :: SubCat } instance Show Item where show (Item cat subCat) = "Item " <> show cat <> " " <> show subCat
But there are some restrictions between its category and sub category. If its category is Cat1, its sub category must be one of SubCat1 or SubCat2. If its category is Cat2, its sub category must be one of SubCat2 or SubCat3.
To prevent someone from creating an invalid item, we can check this relation in a factory function buildItem, and export it from the module without exporting Item data constructor.
validSubCats :: Cat -> [SubCat] validSubCats Cat1 = [SubCat1, SubCat2] validSubCats Cat2 = [SubCat2, SubCat3] buildItem :: Cat -> SubCat -> Maybe Item buildItem cat subCat | subCat `elem` validSubCats cat = Just $ Item cat subCat buildItem _ _ = Nothing makeItem :: String -> String -> Maybe Item makeItem cat subCat = join $ buildItem <$> readMaybe cat <*> readMaybe subCat
This works, but is it possible to put this a bit further and express this relation in types? I'll try it in this series of posts. The goal is expressing this relation in types while supporting building an item from strings and printing it.
For example, you can write something like this with the current code. How will it look like after we make it type-safe?
main :: IO () main = do let items :: [Item] items = catMaybes [ buildItem Cat1 SubCat2 , makeItem "Cat2" "SubCat3" , makeItem "Cat2" "SubCat1" ] mapM_ print items
0 notes