Upgrade to Pro — share decks privately, control downloads, hide ads and more …

型レベル数値リテラル

 型レベル数値リテラル

Tomohiko Himura

May 09, 2016
Tweet

More Decks by Tomohiko Himura

Other Decks in Programming

Transcript

  1. ghci> :info Num class Num a where (+) :: a

    -> a -> a (-) :: a -> a -> a (*) :: a -> a -> a negate :: a -> a abs :: a -> a signum :: a -> a fromInteger :: Integer -> a -- Defined in ‘GHC.Num’ instance Num Word -- Defined in ‘GHC.Num’ instance Num Integer -- Defined in ‘GHC.Num’ instance Num Int -- Defined in ‘GHC.Num’ instance Num Float -- Defined in ‘GHC.Float’ instance Num Double -- Defined in ‘GHC.Float’
  2. ghci> :type 1 :: Int 1 :: Int :: Int

    「1 :: Int」の型は Intです
  3. ghci> :type 1 :: Word 1 :: Word :: Word

    ghci> :type 1 :: Float 1 :: Float :: Float
  4. ghci> :type undefined undefined :: t ghci> :type undefined ::

    Int undefined :: Int :: Int ghci> :type undefined :: String undefined :: String :: String
  5. ghci> :set -XDataKinds ghci> :type undefined :: 1 <interactive>:1:14: Expected

    a type, but ‘1’ has kind ‘GHC.TypeLits.Nat’ In an expression type signature: 1 In the expression: undefined :: 1
  6. ghci> let add = \x y -> x + y

    :: Int ghci> :type add add :: Int -> Int -> Int ghci> :kind Int -> Int -> Int Int -> Int -> Int :: *
  7. ghci> :kind [] [] :: * -> * ghci> :kind

    Maybe Maybe :: * -> * ghci> :kind Num Num :: * -> GHC.Prim.Constraint ghci> :kind Monad Monad :: (* -> *) -> GHC.Prim.Constraint
  8. ghci> import Data.Proxy ghci> :kind Proxy Proxy :: k ->

    * ghci> :kind Proxy 1 Proxy 1 :: *
  9. ghci> :type Proxy :: Proxy 1 Proxy :: Proxy 1

    :: Proxy 1 undefinedをつかってきましたが 「Proxy n」な型の値はProxyで作れる
  10. ghci> :kind 1 + 1 <interactive>:1:3: Illegal operator ‘+’ in

    type ‘1 + 1’ Use TypeOperators to allow operators in types
  11. ghci> :set -XTypeOperators ghci> :kind 1 + 1 <interactive>:1:3: Not

    in scope: type constructor or class ‘+’
  12. ghci> :kind 1 GHC.TypeLits.+ 1 1 GHC.TypeLits.+ 1 :: GHC.TypeLits.Nat

    ghci> import GHC.TypeLits ghci> :kind 1 + 1 1 + 1 :: Nat
  13. ghci> :kind! 2 * 3 2 * 3 :: Nat

    = 6 ghci> :kind! 6 - 2 6 - 2 :: Nat = 4 ghci> :kind! 2 ^ 3 2 ^ 3 :: Nat = 8 他にもいろいろできます
  14. ghci> :kind! 2 <=? 3 2 <=? 3 :: Bool

    = 'True ghci> :kind! 4 <=? 3 4 <=? 3 :: Bool = 'False ghci> :kind! 2 <= 3 2 <= 3 :: GHC.Prim.Constraint = 'True ~ 'True ghci> :kind! 4 <= 3 4 <= 3 :: GHC.Prim.Constraint = 'False ~ 'True 比較もできます
  15. ghci> :type Proxy :: Proxy (1 + 1) Proxy ::

    Proxy (1 + 1) :: Proxy 2 ghci> natVal (Proxy :: Proxy (1 + 1)) 2
  16. {-# LANGUAGE DataKinds #-} {-# LANGUAGE TypeOperators #-} import Data.Proxy

    import GHC.TypeLits hoge1 :: Proxy 1 hoge1 = Proxy hoge2 :: Proxy 2 hoge2 = Proxy hoge3 :: Proxy 3 hoge3 = Proxy hoge4 :: Proxy 4 hoge4 = Proxy add' :: Proxy x -> Proxy y -> Proxy (x + y) add' _ _ = Proxy mul' :: Proxy x -> Proxy y -> Proxy (x * y) mul' _ _ = Proxy div' :: Proxy (x * y) -> Proxy x -> Proxy y div' _ _ = Proxy
  17. ghci> hoge1 Proxy ghci> :type hoge1 hoge1 :: Proxy 1

    ghci> hoge2 Proxy ghci> :type hoge2 hoge2 :: Proxy 2 ghci> add' hoge1 hoge2 Proxy ghci> :type add' hoge1 hoge2 add' hoge1 hoge2 :: Proxy 3 ghci> :type mul' hoge2 hoge4 mul' hoge2 hoge4 :: Proxy 8 ghci> :type div' hoge4 hoge2 div' hoge4 hoge2 :: Proxy 2
  18. • 「値に型がある」ように「型には種がある」 • Haskellには型レベルのリテラルがある • 型レベルの演算子もある • :kind! で型レベルの式を評価できる •

    kindが*にならないと式としてつかえない • (要出典) • 手軽に*にする方法としてProxyがある • 自分でもつくれます(未解説) • :set -X をつかえばghciでもGHC拡張が使える