defargs (empty) → 0.1
raw patch · 4 files changed
+180/−0 lines, 4 filesdep +basedep +clusssetup-changed
Dependencies added: base, cluss
Files
- LICENSE +28/−0
- Setup.hs +2/−0
- defargs.cabal +35/−0
- src/Type/DefArgs.hs +115/−0
+ LICENSE view
@@ -0,0 +1,28 @@+Copyright (c) 2014, Yusuke Matsushita+All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++* Redistributions of source code must retain the above copyright notice, this+ list of conditions and the following disclaimer.++* Redistributions in binary form must reproduce the above copyright notice,+ this list of conditions and the following disclaimer in the documentation+ and/or other materials provided with the distribution.++* Neither the name of defargs nor the names of its+ contributors may be used to endorse or promote products derived from+ this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.+
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ defargs.cabal view
@@ -0,0 +1,35 @@+name: defargs +category: type system +version: 0.1 +license: BSD3 +license-file: LICENSE +cabal-version: >= 1.10 +tested-with: GHC==7.8.3 +author: Yusuke Matsushita +maintainer: Yusuke Matsushita <y.skm24t@gmail.com> +stability: provisional +homepage: https://github.com/Kinokkory/defargs +bug-reports: https://github.com/Kinokkory/defargs/issues +copyright: (c) Yusuke Matsushita 2014 +synopsis: default arguments in haskell +description: Default arguments in Haskell. + +build-type: Simple + +source-repository head + type: git + location: git@github.com:Kinokkory/defargs.git + +library + hs-source-dirs: src + default-language: Haskell2010 + other-extensions: + Trustworthy, + TypeOperators, ScopedTypeVariables, TypeFamilies, + ConstraintKinds, DataKinds, + MultiParamTypeClasses, FlexibleContexts, FlexibleInstances, UndecidableInstances + build-depends: + base ==4.*, + cluss >=0.2 + exposed-modules: Type.DefArgs + ghc-options: -Wall
+ src/Type/DefArgs.hs view
@@ -0,0 +1,115 @@+{-# LANGUAGE + Trustworthy, + TypeOperators, ScopedTypeVariables, TypeFamilies, + ConstraintKinds, DataKinds, + MultiParamTypeClasses, FlexibleContexts, FlexibleInstances, UndecidableInstances #-} + +-------------------------------------------------------------------------------- +-- | +-- Module: Type.DefArgs +-- Copyright: (c) Yusuke Matsushita 2014 +-- License: BSD3 +-- Maintainer: Yusuke Matsushita +-- Stability: provisional +-- Portability: portable +-- +-- Default arguments in Haskell. +-------------------------------------------------------------------------------- + +module Type.DefArgs ( + -- * Example + -- $example + + -- * Def + Def(..) + + -- * Converters + -- $converters + , defarg, defargs2, defargs3, defargs4, defargs5 + , defargs6, defargs7, defargs8, defargs9, defargs10) where + +import Type.Cluss + +-- | When used as an argument, 'Def' will be replaced with the corresponding default value by 'defarg', 'defargs2', ..., and 'defargs10'. +data Def = Def + +-- heterogeneous list +data Nil = Nil +data a * b = Cons a b +(&) :: a -> b -> a * b +(&) = Cons +infixr 0 *, & + +-- core +class DefArgs f as where + type P f as ::[*] + defargs' :: In (P f as) g => f -> as -> g +instance DefArgs r Nil where + type P r Nil = '[Type r] + defargs' x Nil = projI ( + x `andI` + noneI :: AllOfI '[Type r]) +instance DefArgs f as => DefArgs (a -> f) (a * as) where + type P (a -> f) (a * as) = [Unary ((->) Def) (In (P f as)), Unary ((->) a) (In (P f as))] + defargs' f (Cons x xs) = projI ( + (\Def -> defargs' (f x) xs) `andI1` + (\x' -> defargs' (f x') xs) `andI1` + noneI :: AllOfI (P (a -> f) (a * as))) + +-- the constraint +type Good f d g = (DefArgs f d, In (P f d) g) + +-- $converters +-- Given a function, these converters provide every argument of the function with a default value. +-- 'defarg' is used for a function of one argument, 'defargs2' is used for a function of two arguments, and so on. +-- +-- The converters require concrete types for the type variables @a, b, c, ...@; +-- they need concrete types in order to judge whether a type is 'Def' or non-'Def'. +-- Internally, the judgment is made by <http://hackage.haskell.org/package/cluss cluss>. + +-- converters +defarg :: Good (a -> r) (a * Nil) (a' -> r) => (a -> r) -> a -> (a' -> r) +defarg f x = defargs' f (x & Nil) +defargs2 :: Good (a -> b -> r) (a * b * Nil) (a' -> b' -> r) => (a -> b -> r) -> a -> b -> (a' -> b' -> r) +defargs2 f x x2 = defargs' f (x & x2 & Nil) +defargs3 :: Good (a -> b -> c -> r) (a * b * c * Nil) (a' -> b' -> c' -> r) => (a -> b -> c -> r) -> a -> b -> c -> (a' -> b' -> c' -> r) +defargs3 f x x2 x3 = defargs' f (x & x2 & x3 & Nil) +defargs4 :: Good (a -> b -> c -> d -> r) (a * b * c * d * Nil) (a' -> b' -> c' -> d' -> r) => (a -> b -> c -> d -> r) -> a -> b -> c -> d -> (a' -> b' -> c' -> d' -> r) +defargs4 f x x2 x3 x4 = defargs' f (x & x2 & x3 & x4 & Nil) +defargs5 :: Good (a -> b -> c -> d -> e -> r) (a * b * c * d * e * Nil) (a' -> b' -> c' -> d' -> e' -> r) => (a -> b -> c -> d -> e -> r) -> a -> b -> c -> d -> e -> (a' -> b' -> c' -> d' -> e' -> r) +defargs5 f x x2 x3 x4 x5 = defargs' f (x & x2 & x3 & x4 & x5 & Nil) +defargs6 :: Good (a -> b -> c -> d -> e -> f -> r) (a * b * c * d * e * f * Nil) (a' -> b' -> c' -> d' -> e' -> f' -> r) => (a -> b -> c -> d -> e -> f -> r) -> a -> b -> c -> d -> e -> f -> (a' -> b' -> c' -> d' -> e' -> f' -> r) +defargs6 f x x2 x3 x4 x5 x6 = defargs' f (x & x2 & x3 & x4 & x5 & x6 & Nil) +defargs7 :: Good (a -> b -> c -> d -> e -> f -> g -> r) (a * b * c * d * e * f * g * Nil) (a' -> b' -> c' -> d' -> e' -> f' -> g' -> r) => (a -> b -> c -> d -> e -> f -> g -> r) -> a -> b -> c -> d -> e -> f -> g -> (a' -> b' -> c' -> d' -> e' -> f' -> g' -> r) +defargs7 f x x2 x3 x4 x5 x6 x7 = defargs' f (x & x2 & x3 & x4 & x5 & x6 & x7 & Nil) +defargs8 :: Good (a -> b -> c -> d -> e -> f -> g -> h -> r) (a * b * c * d * e * f * g * h * Nil) (a' -> b' -> c' -> d' -> e' -> f' -> g' -> h' -> r) => (a -> b -> c -> d -> e -> f -> g -> h -> r) -> a -> b -> c -> d -> e -> f -> g -> h -> (a' -> b' -> c' -> d' -> e' -> f' -> g' -> h' -> r) +defargs8 f x x2 x3 x4 x5 x6 x7 x8 = defargs' f (x & x2 & x3 & x4 & x5 & x6 & x7 & x8 & Nil) +defargs9 :: Good (a -> b -> c -> d -> e -> f -> g -> h -> i -> r) (a * b * c * d * e * f * g * h * i * Nil) (a' -> b' -> c' -> d' -> e' -> f' -> g' -> h' -> i' -> r) => (a -> b -> c -> d -> e -> f -> g -> h -> i -> r) -> a -> b -> c -> d -> e -> f -> g -> h -> i -> (a' -> b' -> c' -> d' -> e' -> f' -> g' -> h' -> i' -> r) +defargs9 f x x2 x3 x4 x5 x6 x7 x8 x9 = defargs' f (x & x2 & x3 & x4 & x5 & x6 & x7 & x8 & x9 & Nil) +defargs10 :: Good (a -> b -> c -> d -> e -> f -> g -> h -> i -> j -> r) (a * b * c * d * e * f * g * h * i * j * Nil) (a' -> b' -> c' -> d' -> e' -> f' -> g' -> h' -> i' -> j' -> r) => (a -> b -> c -> d -> e -> f -> g -> h -> i -> j -> r) -> a -> b -> c -> d -> e -> f -> g -> h -> i -> j -> (a' -> b' -> c' -> d' -> e' -> f' -> g' -> h' -> i' -> j' -> r) +defargs10 f x x2 x3 x4 x5 x6 x7 x8 x9 x10 = defargs' f (x & x2 & x3 & x4 & x5 & x6 & x7 & x8 & x9 & x10 & Nil) + +-- $example +-- Here is a simple example. +-- +-- >{-# LANGUAGE NoMonomorphismRestriction #-} +-- > +-- >import Type.DefArgs +-- > +-- >test = defargs2 (\x y -> x ++ ", " ++ y ++ "!") "hello" "world" +-- >test2 = defargs2 (+) (10 :: Int) 100 +-- > +-- >main = do +-- > putStrLn $ test Def Def +-- > putStrLn $ test "good morning" Def +-- > putStrLn $ test Def "kitty" +-- > putStrLn $ test "oh" "yeah" +-- > print $ test2 (90 :: Int) Def +-- +-- This is the result. +-- +-- >hello, world! +-- >good morning, world! +-- >hello, kitty! +-- >oh, yeah! +-- >190