packages feed

defargs (empty) → 0.1

raw patch · 4 files changed

+180/−0 lines, 4 filesdep +basedep +clusssetup-changed

Dependencies added: base, cluss

Files

+ 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