QIFOPNFOBFYQSFTTFEBT%J⒎FSFOUJBM&RVBUJPOT w 4QFFE4DBMF#JMMJPODFMMTºWBMTº.4UFQT #GSFFEPNº.JMMJPO4UFQT w 0VSTPMWFSJTDVSSFOUMZXSJUUFOJO -JOFTPG)BTLFMM BOEDPOTJTUTPGQBDLBHFT
1SJNJUJWF.POBET 3FXSJUJOH3VMFT 4QFDJBMJTBUJPO *OUFSQSPDFTT DPNNVOJDBUJPO w .POBEJD4FRVFODF"CTUSBDUJPOUPNBLFVTFPGUIFTF w 1MVHJOTVTJOH&YUFOTJCMF3FDPSET w "OENBOZPUIFSUFDIOJRVFTOPUNFOUJPOFEUIJTUBML &YQSFTTJWJUZ4BGFUZ .PEVMBSJUZ &YUFOTJCJMJUZ
1SJNJUJWF.POBET 3FXSJUJOH3VMFT 4QFDJBMJTBUJPO *OUFSQSPDFTT DPNNVOJDBUJPO w .POBEJD4FRVFODF"CTUSBDUJPOUPNBLFVTFPGUIFTF w 1MVHJOTVTJOH&YUFOTJCMF3FDPSET w "OENBOZPUIFSUFDIOJRVFTOPUNFOUJPOFEUIJTUBML &YQSFTTJWJUZ4BGFUZ
CVUUIFZ BSFDPNQMFUFMZEJ⒎FSFOURVOBUJUJFT w "OEUIFZSFRVJSFTEJ⒎FSFOUQSFQSPDFTTJOHPGCPVOEBSZ WBMVFTUPFOGPSDFJOWBSJBOUT w 1SPDFTTFEWBMVFTNVTUOPUCFBEEFENVMUJQMJFEXJUIPUIFS WBMVFT CFDBVTFJUDBOWJPMBUFJOWBSJBOUT
:FU%POF B %FQFOEFOU5ZQF w 8FDBOVTF,OPXO/BUMJLFDPOTUSBJOUTUPSFJGZUZQFMFWFMWBMVFTUPFYQSFTTJPO w 4JODFXFXBOUUPBMMPXPQFSBUJPOTPOMZPOYetRVBOUJUJFT XFQSPWJEFNumsPOMZ GPSYets BOEIJEFDPOTUSVDUPSTGSPNPUIFSNPEVMFT w /VNJOTUBODFJTJOEFQPGLBOEOBNF XFDBOKVTUXSJUFBQPMZNPSQIJDJOTUT data Sanity = Yet | Done newtype TagQty name (s Sanity) = TQty { unTagQty PhysQty } unproc TagQty k t 'Done TagQty t 'Yet class Processable env k name where process env PhysQty TagQty name 'Done instance s ~ 'Yet Num (TagQty k name s)
POMZPO VOQSPDFTTFERUZT BOETPPO w 4VDIQBSBNFUFSTXIJDIEPFTOUPDDVSJOBDUVBMWBMVFJTDBMMFE QIBOUPNUZQFT w ()$JTOPUTPDMFWFSUPTPMWFUSJWJBMDPOTUSBJOUT CVUPOFDBOBVHNFOU UIFNXJUIUZQFDIFDLFSQMVHJOT
POMZPO VOQSPDFTTFERUZT BOETPPO w 4VDIQBSBNFUFSTXIJDIEPFTOUPDDVSJOBDUVBMWBMVFJTDBMMFE QIBOUPNUZQFT w ()$JTOPUTPDMFWFSUPTPMWFUSJWJBMDPOTUSBJOUT CVUPOFDBOBVHNFOU UIFNXJUIUZQFDIFDLFSQMVHJOT w /PUFGPS1SPGFTTJPOBMT8FBSFUSZJOHIBSEUPBWPJEUPVTFTJOHMFUPOT
1SJNJUJWF.POBET 3FXSJUJOH3VMFT 4QFDJBMJTBUJPO *OUFSQSPDFTT DPNNVOJDBUJPO w .POBEJD4FRVFODF"CTUSBDUJPOUPNBLFVTFPGUIFTF w 1MVHJOTVTJOH&YUFOTJCMF3FDPSET w "OENBOZPUIFSUFDIOJRVFTOPUNFOUJPOFEUIJTUBML &YQSFTTJWJUZ4BGFUZ
1SJNJUJWF.POBET 3FXSJUJOH3VMFT 4QFDJBMJTBUJPO *OUFSQSPDFTT DPNNVOJDBUJPO w .POBEJD4FRVFODF"CTUSBDUJPOUPNBLFVTFPGUIFTF w 1MVHJOTVTJOH&YUFOTJCMF3FDPSET w "OENBOZPUIFSUFDIOJRVFTOPUNFOUJPOFEUIJTUBML .PEVMBSJUZ
FBDITFQBSBUFUBTLT w %J⒎FSFOUJBMPQFSBUJPOT DBMDVMBUJPOTDIFNBUB *0 w &RVBUJPOXSJUFSTIBTUPDBSFBCPVUPOMZBCTUSBDUEJ⒎FSFOUJBM PQFSBUJPOTPOMZ w #BDLFOE 4PMWFS XSJUFSTDBOJNQMFNFOUUIFNDPODSFUFMZ MFBWJOHFRVBUJPOTUIFNTFMWFTVOUPVDIFE
m where grad PhysQty m m (PhysQty m) div PhysQty m m (PhysQty m) w "CTUSBDUDPNNPOPQFSBUJPOBTBNPOBEJDGVODUJPO w "DUVBMMZ diffOFFETTPNFHFPNFUSJDJOGPBTBOFYUSBBSHVNFOU CVUJUJTIJEEFOJOMonadic value m w 5IJTIJEFTUIFJNQMEFUBJMPGEJ⒎PQTBOEFOBCMFTVTUPTFQBSBUFJNQM GSPNBCTUSBDUFRVBUJPOT5IJTFODPVSBHFTNPEVMBSJUZBOEHFOFSBMJUZ
IO w 5IFMBUUFSJTDBMMFE3*0QBUUFSOJO)BTLFMMDPNNVOJUZ w (JWFTVTVOJGPSNUSFBUNFOUGPSCPUIJNNVUBCMF TUBUFTZFUSFUBJOJOHUISFBEBOEFYDFQUJPOTBGFUZ w 8FVTFDerivingViaUPSFEVDFCPJMFSQMBUFDPEFTGPS TVDIJOTUBODFT
Expr m a where Join Expr m (Expr m a) Expr m a Grad (ToPhysQty m qty) Expr m qty Expr m (PhysQty m) grad' (ToPhysQty m a) a Expr m (PhysQty m) grad' = Grad . toExpr -- pre-process for conversion
1SJNJUJWF.POBET 3FXSJUJOH3VMFT 4QFDJBMJTBUJPO *OUFSQSPDFTT DPNNVOJDBUJPO w .POBEJD4FRVFODF"CTUSBDUJPOUPNBLFVTFPGUIFTF w 1MVHJOTVTJOH&YUFOTJCMF3FDPSET w "OENBOZPUIFSUFDIOJRVFTOPUNFOUJPOFEUIJTUBML .PEVMBSJUZ
1SJNJUJWF.POBET 3FXSJUJOH3VMFT 4QFDJBMJTBUJPO *OUFSQSPDFTT DPNNVOJDBUJPO w .POBEJD4FRVFODF"CTUSBDUJPOUPNBLFVTFPGUIFTF w 1MVHJOTVTJOH&YUFOTJCMF3FDPSET w "OENBOZPUIFSUFDIOJRVFTOPUNFOUJPOFEUIJTUBML
w 4USFBNBNPOBEJDHFOFSBUJOHGVODUJPO w #VOEMF4USFBN PQUJPOBMDPODSFUFWFDUPSWBMVFBOEMFOHUI JOGPSNBUJPO w TUSFBNVOTUSFBNGVODUJPOTDPOWFSUT7FDUPSTUPGSPN#VOEMFT f z ∘ g ≡ (f ∘ g) z
#PPM w 4UPSBCMFGPSDPNNVOJDBUJPOTXJUI$MJCSBSZ w BOENPOPNPSQIJDOFXUZQFXSBQQFSTBSPVOEUIFN w 1SPCMFN8FXBOUUPUSFBUUIFNVOJGPSNMZ w $BOXFEPUIJTSFUBJOJOHF⒏DJFODZPGWFDUPST
Monad m MSeq m seq where imap (Key seq Elem seq Elem seq) seq m seq index Index seq seq m (Elem seq) ifoldr (Key seq Elem seq Elem seq) accum instance Monad m MSeq m (Vector a) instance Monad m MSeq m (VecMap k a) .POBEJDSFTVMU w 1SPCMFN.POBEJDSFTVMUNJHIUTBDSJpDFTUSFBNGVTJPO w 1SPCMFN)BWFUPJNQMFNFOUWFDUPSPQFSBUJPOTBMMCZIBOET .BOZPUIFSPQT
(Monad m) MSequence m seq where unfoldrM (s m (Maybe (Elem seq, s))) s m seq indexM' seq Int m (Elem seq) stream' seq B.Bundle m (VecRep seq) (Elem seq) unstream' B.Bundle m (VecRep seq) (Elem seq) m seq
(Monad m) MSequence m seq where unfoldrM (s m (Maybe (Elem seq, s))) s m seq indexM' seq Int m (Elem seq) stream' seq B.Bundle m (VecRep seq) (Elem seq) unstream' B.Bundle m (VecRep seq) (Elem seq) m seq w "MMPUIFSPQFSBUJPOTBSFEFSJWFEGSPNUIFTFQSJNJUJWFTXJUI Data.Vector.Fusion.Bundle.MonadicNPEVMF
(Monad m) MSequence m seq where unfoldrM (s m (Maybe (Elem seq, s))) s m seq indexM' seq Int m (Elem seq) stream' seq B.Bundle m (VecRep seq) (Elem seq) unstream' B.Bundle m (VecRep seq) (Elem seq) m seq w "MMPUIFSPQFSBUJPOTBSFEFSJWFEGSPNUIFTFQSJNJUJWFTXJUI Data.Vector.Fusion.Bundle.MonadicNPEVMF w 0OFDBOFYQMPJUGVTJPOSVMFTQSPWJEFECZWFDUPSQBDLBHFGPSGSFF
(Monad m) MSequence m seq where unfoldrM (s m (Maybe (Elem seq, s))) s m seq indexM' seq Int m (Elem seq) stream' seq B.Bundle m (VecRep seq) (Elem seq) unstream' B.Bundle m (VecRep seq) (Elem seq) m seq w "MMPUIFSPQFSBUJPOTBSFEFSJWFEGSPNUIFTFQSJNJUJWFTXJUI Data.Vector.Fusion.Bundle.MonadicNPEVMF w 0OFDBOFYQMPJUGVTJPOSVMFTQSPWJEFECZWFDUPSQBDLBHFGPSGSFF w #POVT)FUFSPHFOFPVT$PNCJOBUPSTBOE1SJN.POBEPQUJNJTBUJPO
m s, MSeq m t, MSeq m u, Key s ~ Key t, Key s ~ Key u) (Elem s Elem t Elem u) s t m u hzipWithM f = \as bs unstream $ B.zipWithM f (B.reVector $ stream as) (B.reVector $ stream bs)
3FXSJUJOH3VMFTDBOIFMQSFEVDFPWFSIFBEIFSF w *GUIFSFTVMUUZQFJTNPOBEJD UIFOPOFDBOFYQMPJU1SJN.POBE JOTUBODFUPHBJONPSFTQFFE SFUBJOJOHEFDMBSBUJWFNBOOFS w 5IJTDPNQPTFTXFMMXJUIUBHMFTTpOBMTUZMFBQQSPBDI JNQMFNFOUFEXJUI3*0QBUUFSO w %FTUSVDUJWFBTTJHONFOUT EJTHVJTFEBTEFDMBSBUJWF DPNCJOBUPST BSFJOEFFEZPVSGSJFOET
1SJNJUJWF.POBET 3FXSJUJOH3VMFT 4QFDJBMJTBUJPO *OUFSQSPDFTT DPNNVOJDBUJPO w .POBEJD4FRVFODF"CTUSBDUJPOUPNBLFVTFPGUIFTF w 1MVHJOTVTJOH&YUFOTJCMF3FDPSET w "OENBOZPUIFSUFDIOJRVFTOPUNFOUJPOFEUIJTUBML
1SJNJUJWF.POBET 3FXSJUJOH3VMFT 4QFDJBMJTBUJPO *OUFSQSPDFTT DPNNVOJDBUJPO w .POBEJD4FRVFODF"CTUSBDUJPOUPNBLFVTFPGUIFTF w 1MVHJOTVTJOH&YUFOTJCMF3FDPSET w "OENBOZPUIFSUFDIOJRVFTOPUNFOUJPOFEUIJTUBML &YUFOTJCJMJUZ
data PConfig p Type type POutput p Type type PlugM p (m * *) Constraint pluginOptionP OptParser (PConfig p) setupState MonadIO m PConfig p m (PState p) initialise (p ∈ ps, MonadPlugins ps m, PlugM p m) proxy p Info m Info finalise (p ∈ ps, MonadPlugins ps m, PlugM p m) proxy p Info m Info genOutput (p ∈ ps, MonadPlugins ps m, PlugM p m) PConfig p m (POutput p)
PSB { p PState p | p ∈ ps } w 0OFDBOTJNVMBUFTVDIEBUBUZQFTXJUI )JHIFS,JOEFE &YUFOTJCMF3FDPSET JOUIJTDBTF ),)-JTUTV⒏DFT UIPVHI w "OFOUJSF4PMWFSXJUIQMVHJOTpsNVTULFFQJOGP BTTPDJBUFEUPFBDIQMVHJOBTBCVOEMF TPNFUIJOHMJLF Solver '[] -- Solver without any Plugin Solver '[A, B, C] -- Solver with Plugins A, B and C
∈ ps PState p WBMVFJOstates PStateB psDBOCF SFUSJFWFECZstates ^. hfieldL @p w 5IFSFBSFQMFOUZPGFYJTUJOHMJCT extensible, vinyl, superrecords,FUD GPSFYUSFDTCVUXFJNQMECZPVSTFMWFTGPSTPNFSFBTPOT w ),%PQT TVDIBTCGPMES.CGPMEM. .FNCFSDPOTUS DBOCFVTFEUP QSPDFTTCVOEMFTCBDLXBSEGPSXBSE type PBundle h ps = Record h (IdentFields ps) type PStateB ps = PBundle PState ps
(Labels xs) Record h xs l := (h (ElemAt (Idx l (Labels xs)) (Vals xs)) h a) Record h ((l a) |< xs) Record hl &%~ (_ := f) = Record $ gcastWith (takeMapApply @Entry' @(Index l (Labels xs)) @xs) $ gcastWith (dropMapApply @Entry' @(Index l (Labels xs) + 1) @xs) $ gcastWith (mapApplyAppend @Entry' @(Take (Index l (Labels xs)) xs) @((l a) ': Drop (Index l (Labels xs) + 1) xs) ) $ hmodify' (Proxy @(Index l (Labels xs))) f hl 5SJWJBMIBOEXSJUUFOQSPPGT .BQI YT ZT .BQIYT .BQIZT
(Labels xs) Record h xs l := (h (ElemAt (Idx l (Labels xs)) (Vals xs)) h a) Record h ((l a) |< xs) Record hl &%~ (_ := f) = Record $ gcastWith (takeMapApply @Entry' @(Index l (Labels xs)) @xs) $ gcastWith (dropMapApply @Entry' @(Index l (Labels xs) + 1) @xs) $ gcastWith (mapApplyAppend @Entry' @(Take (Index l (Labels xs)) xs) @((l a) ': Drop (Index l (Labels xs) + 1) xs) ) $ hmodify' (Proxy @(Index l (Labels xs))) f hl 5SJWJBMIBOEXSJUUFOQSPPGT .BQI YT ZT .BQIYT .BQIZT
xs h a. Member l (Labels xs) Record h xs l := (h (ElemAt (Idx l (Labels xs)) (Vals xs)) h a) Record h ((l a) |< xs) Record hl &%~ (_ := f) = Record $ hmodify' (Proxy @(Index l (Labels xs))) f hl
CVUTJNQMFWBMVFMFWFMGPMEJOHPGUZQFMFWFMMJTUT JTBMTPVTFGVM w "LJOEPGSPXQPMZNPSQIJTNDBOBMTPCFVTFEUPUSFBUBCVOEMFPG QIZTJDBMRVBOUJUJFTQPMZNPSQIJDBMMZ w 8FEFWJTFEDVTUPN&YU3FDMJCSBSZXJUI
CVUTJNQMFWBMVFMFWFMGPMEJOHPGUZQFMFWFMMJTUT JTBMTPVTFGVM w "LJOEPGSPXQPMZNPSQIJTNDBOBMTPCFVTFEUPUSFBUBCVOEMFPG QIZTJDBMRVBOUJUJFTQPMZNPSQIJDBMMZ w 8FEFWJTFEDVTUPN&YU3FDMJCSBSZXJUI w 1PMZNPSQIJDMBCFMT GBTUJOEFYJOH BVUPNBUJDDPOTUSBJOUTPMWJOH BTTJTUFECZ5ZQFDIFDLFSQMVHJOT
w ()$T%FQFOEFOU5ZQFTIFMQTFYUFOTJCJMJUZBOELFFQJOHJOWBSJBOUT w )VNBOT'PSHFU-FU5ZQFT3FNFNCFS w %FQFOEFOU5ZQFTBOE%FTUSVDUJWF"TTJHONFOUTBSFZPVSGSJFET w 8FBSFQMBOOJOHUPQVCMJTIJOUFSOBMMJCSBSJFT JOOPUTPGBSGVUVSF IPQFGVMMZ w 4UJMM UIFSFBSFNBOZUIJOHTUPCFJNQSPWFE
Coutts, R. Leshchinskiy and D. Stewart, Stream Fusion: From Lists to Streams to Nothing at All. 3. G. Mainland, R. Leshchinskiy and SPJ, Exploiting Vector Instructions with Generalized Stream Fusion. 4. ghc-typelits-natnormalise package
w ()$T%FQFOEFOU5ZQFTIFMQTFYUFOTJCJMJUZBOELFFQJOHJOWBSJBOUT w )VNBOT'PSHFU-FU5ZQFT3FNFNCFS w %FQFOEFOU5ZQFTBOE%FTUSVDUJWF"TTJHONFOUTBSFZPVSGSJFET w 8FBSFQMBOOJOHUPQVCMJTIJOUFSOBMMJCSBSJFT JOOPUTPGBSGVUVSF IPQFGVMMZ w 4UJMM UIFSFBSFNBOZUIJOHTUPCFJNQSPWFE