今回の例: ScopedTypeVariables、TypeApplicationsとの組み合わせ
何か全然よくわからない、
そういえばHaskell初心者だった頃によくGHCサジェストされた気がする
AllowAmbiguousTypes
プラグマですが、
初めて「お前を使わせてくれ!」っていう場面に遭遇しました。
こちらです
{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
check :: forall a. (Group a, Eq a) => Bool
check = (empty :: a) <> empty == empty
main :: IO ()
main = do
smallCheck 2 $ check @Sum
smallCheck 2 $ check @RSum
newtype Sum = Sum
{ unSum :: Int
} deriving (Show, Eq, Num, Enum)
newtype RSum = RSum
{ unRSum :: Rational
} deriving (Show, Eq, Num, Enum)
class Monoid a => Group a where
inverse :: a -> a
instance Group Sum where
inverse = negate
instance Group RSum where
inverse = negate
instance Group () where
inverse () = ()
これは何?
最近は技術書典5で出す「矢澤にこ先輩といっしょに代数!」という本を書いているのですが
技術書典5に当選しました🎉✨✨
— あいや🤘🙄🤘技術書典5@か74 (@public_ai000ya) 2018年8月3日
にこちゃんがHaskellで数学を教えてくれる本を出します!#技術書典#技術書典5https://t.co/Ev4BPQX1PT pic.twitter.com/SGQtFopgdD
群の章を書いているところで
「任意の群はe * e = e
だっけ?」
という疑問に駆られたので、
その確認を行ったものです。
check :: forall a. (Group a, Eq a) => Bool
check = (empty :: a) <> empty == empty
smallCheck 2 $ check @Sum
smallCheck 2 $ check @RSum
ここでa
は引数に表れていないのでAllowAmbiguousTypes
が必要になり、
ScopedTypeVariables
によりa
を文中で使用。
そして使用側でその群インスタンスの型を…
引数に依らず指定しています。
引数に依らないというところが、
AllowAmbiguousTypes
が必要になる要点でした
宣伝
技術書典5に出した後は、
Boothでの電子書籍での販売を予定しております
技術書典5に当選しました🎉✨✨
— あいや🤘🙄🤘技術書典5@か74 (@public_ai000ya) 2018年8月3日
にこちゃんがHaskellで数学を教えてくれる本を出します!#技術書典#技術書典5https://t.co/Ev4BPQX1PT pic.twitter.com/SGQtFopgdD
よろしくお願いします!