Data.Defaultのdefの使い方を見てみた

はじめに

homedogheavy.hatenablog.com

def がよくわからなかったので Data.Default 見直すぞーと言ってたので見直した。 名前の通りデフォルト値を決める感じのあれこれなんだなーという理解までは行けた気がする。

参考コード

  • 上記の記事の該当部分だけいい感じに抜き出します
  • defを使うのと使わないのとでそれぞれClientHooksを用意
import qualified Data.Default as D
import qualified Network.TLS as T


-- ClientHooks
hooks = T.ClientHooks
          { T.onCertificateRequest = \_ -> return Nothing
          , T.onServerCertificate = \_ _ _ _ -> return []
          }

-- def を使った ClientHooks
defHooks = D.def
          { T.onCertificateRequest = \_ -> return Nothing
          , T.onServerCertificate = \_ _ _ _ -> return []
          }
*Main> :lo def.hs
[1 of 1] Compiling Main             ( def.hs, interpreted )

def.hs:6:9: warning: [-Wmissing-fields]
    • Fields of ‘T.ClientHooks’ not initialised: onSuggestALPN,
                                                 onCustomFFDHEGroup
    • In the expression:
        T.ClientHooks
          {T.onCertificateRequest = \ _ -> return Nothing,
           T.onServerCertificate = \ _ _ _ _ -> return []}
      In an equation for ‘hooks’:
          hooks
            = T.ClientHooks
                {T.onCertificateRequest = \ _ -> return Nothing,
                 T.onServerCertificate = \ _ _ _ _ -> return []}
  |
6 | hooks = T.ClientHooks
  |         ^^^^^^^^^^^^^...
Ok, one module loaded.

警告が出ました。defを使ってないほうでフィールドの指定が足りない的な内容です。 ちなみに、 ClientHooks の内容は以下 hackage.haskell.org

  • onCertificateRequest
  • onServerCertificate
  • onSuggestALPN
  • onCustomFFDHEGroup

ClientHooks を利用する際には上記の定義が必要です。今回は onCertificateRequest, onServerCertificate は定義してます。 onSuggestALPN の値がどうなってるか確認してみます。

*Main> T.onSuggestALPN hooks
*** Exception: def.hs:(6,9)-(9,11): Missing field in record construction onSuggestALPN

*Main> T.onSuggestALPN defHooks
Nothing

defを使わなかった方は Missing field in record construction onSuggestALPN になりました。 defHooks の方はNothingになりました。 ClientHooksonSuggestALPN のデフォルト値として Nothing を設定しているのだと思います。

デフォルト値の指定

ClientHooksonSuggestALPN のデフォルト値は以下で設定しているようです。

hackage.haskell.org

以下該当部分抜粋

defaultClientHooks :: ClientHooks
defaultClientHooks = ClientHooks
    { onCertificateRequest = \ _ -> return Nothing
    , onServerCertificate  = validateDefault
    , onSuggestALPN        = return Nothing
    , onCustomFFDHEGroup   = defaultGroupUsage
    }

instance Default ClientHooks where
    def = defaultClientHooks

defaultClientHooks を定義して ClientHooks のデフォルトにしてるみたいですね。 onSuggestALPNreturn Nothing ですね。

試し

意味ないけどRPGのキャラ設定的なサンプル

  • nameStringdef を使ってます
  • Intdef は 0なので1にしてます
  • parameterParameter のデフォルトを用意して def で入れてます
import Data.Default

data Player = Player {
   name :: String
  ,level :: Int
  ,parameter :: Parameter
}

data Parameter = Parameter {
   str :: Int
  ,int :: Int
  ,luc :: Int
}

defaultPlayer :: Player
defaultPlayer = Player {
  name = def
  ,level = 1
  ,parameter = def
}

instance Default Player where
  def = defaultPlayer


defaultParameter :: Parameter
defaultParameter = Parameter {
   str = 2
  ,int = 3
  ,luc = 4
}

instance Default Parameter where
  def = defaultParameter

所感

Data.Defaultdef の使い方を見てみました。理解レベル1くらいは上がったはず。instancedef の定義の理解が無い感出てきたので次はその辺見るかも