十三日目
時間が開いてしまってやることを忘れたのでまずここのログを読みなおした。メモ残すこと大事だなって思いました()
Windows で Haskell しようかと思って Stack いれたけど cmd 使うこと考えると嫌になってすぐアンインストールしました*1。
7.9
7.10
if
の中になんでも入れれるの便利で java 使ってると羨ましくなる。
型クラス制約付きの引数を具体型によってパターンマッチングはできるのか?
hoge :: (Num a) => a -> String
といった関数がある時、Int
とそれ以外で挙動を変えたい場合はどうすればいいのか?と思って調べたメモ。
データ型の直和型や列挙型をパターンマッチングするのは簡単にできるのですが...
試しに
hoge :: (Num a) => a -> String
hoge (x::Int) = "aaa"
hoge x = "hoge"
などと書くと Perhaps you intended to use ScopedTypeVariables
と言われたのでそうしてみたけど関係なさそう。
しばらく考えたらこういう案件こそ型クラスを使うべきなんだなあと気付きました。
http://stackoverflow.com/questions/4131552/haskell-check-if-integer-or-check-type-of-variable
にある二番目の解答。
import Data.Typeable
isInteger :: (Typeable a) => a -> Bool
isInteger n = typeOf n == typeOf 1
最悪っぽい。
yesnoIf
が簡単に実装できるのは便利だなあという感じ。
7.10
instance Functor [] where
と書くことになるのは、class Functor
が
class Functor f where
fmap :: (a -> b) -> f a -> f b
と宣言されていて、これによって f
自体は 具体型ではなく型コンストラクタになる ためである。
そのため、
class NonyFunctor f where
fmap :: (a -> b) -> f a -> f b
instance Functor Int where
として具体型を入れると
The first argument of ‘Functor’ should have kind ‘* -> *’,
but ‘Int’ has kind ‘*’
In the instance declaration for ‘Functor Int’
と怒られることになる。
7.11
:k Num
とすると Num :: * -> GHC.Prim.Constraint
となった。
これは型クラス制約のことで、 Num a
は型クラス制約となることの現れ。
:k Functor
は Functor :: (* -> *) -> GHC.Prim.Constraint
となり、型コンストラクタを引数に取り型クラス制約になるということ。
感想
- またまた久しぶりになってしまった...
- 型クラス制約と型コンストラクタがごちゃごちゃになってたので 7.11 読んでよかった。
- 段々難しくなってきた気もするけどしばらくブランク空いたからかもしれない