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

型レベル数値リテラル

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.

 型レベル数値リテラル

Avatar for Tomohiko Himura

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拡張が使える