私はHaskellで説明できない振る舞いを見つけました。私は、ReaderT Monadで使用したいレコードタイプに多相関数を格納しようとしています。私がasks
で自分の関数を取得すると、コンパイラはそれを多相として認識せず、関数の最初の出現時に型を修正するようです。レコード型の多態関数Haskell
runReaderT (ask
>>= \(Test f) -> (liftIO . putStrLn $ show (f 2 :: Int))
>> (liftIO . putStrLn $ show (f "hello"))
) (Test id)
だからそれは何かである:これを実行しようとすると
{-# LANGUAGE Rank2Types #-}
data Test = Test {f :: (forall a. a -> a)}
runReaderT (asks f
>>= \f -> (liftIO . putStrLn $ show (f 2 :: Int))
>> (liftIO . putStrLn $ show (f "hello"))
) (Test id)
は、私が手::
Couldn't match expected type ‘Int’ with actual type ‘[Char]’
In the first argument of ‘f’, namely ‘"hello"’
In the first argument of ‘show’, namely ‘(f "hello")’
In the second argument of ‘($)’, namely ‘show (f "hello")’
ただし、次のコードは動作します私はGHCiの中で、この最小限の例を作成しましたasks
で特別?私はこれに関するアドバイスに感謝しています。
で、私はそれが私が間違っていない場合は、ラムダ引数はあなたがない限り、まだ単相です\後に現れる 'F'に関係していると思うようにそれはまた、明示的にタイプを与えるために働く必要がありますそれ以外の場合は – Ingo
ちょうどいいね!Rank2Typesは、RankNTypesにエイリアスされた廃止された拡張です。 (そして、RankNTypesは 'forall'sだけを書くことができます.Ingoの答えの詳細として、GHCで上位ランクの型推論はありません。) – hao