プログラムタイプチェックを次型チェッカーを満足させるために関数型を "ラップする"必要があるのはなぜですか?
{-# LANGUAGE RankNTypes #-}
import Numeric.AD (grad)
newtype Fun = Fun (forall a. Num a => [a] -> a)
test1 [u, v] = (v - (u * u * u))
test2 [u, v] = ((u * u) + (v * v) - 1)
main = print $ fmap (\(Fun f) -> grad f [1,1]) [Fun test1, Fun test2]
しかし、このプログラムは失敗します。
main = print $ fmap (\f -> grad f [1,1]) [test1, test2]
型エラーで:
Grad.hs:13:33: error:
• Couldn't match type ‘Integer’
with ‘Numeric.AD.Internal.Reverse.Reverse s Integer’
Expected type: [Numeric.AD.Internal.Reverse.Reverse s Integer]
-> Numeric.AD.Internal.Reverse.Reverse s Integer
Actual type: [Integer] -> Integer
• In the first argument of ‘grad’, namely ‘f’
In the expression: grad f [1, 1]
In the first argument of ‘fmap’, namely ‘(\ f -> grad f [1, 1])’
直感的に、後者のプログラムは正しく見えます。結局のところ、 以下、一見同等のプログラムが作業を行います。
main = print $ [grad test1 [1,1], grad test2 [1,1]]
これはGHCの型システムの制限のように見えます。 障害の原因、制限の有無、機能のラッピング以外の回避方法(上記Fun
)を知りたい。
(注:これは単相性の制限によって引き起こされていない。NoMonomorphismRestriction
と をコンパイルすることは解決しない。)
これは恐ろしい単相性の制限ですか? –
モノモフィズムの制限ではありません。 – frasertweedale
これは実際にタイプシステムの制限です。失敗したプログラムでは、impredicative型の型チェックを正しく行う必要があります( '[test1、test2] :: [forall a ... ...]'はimpredicativeです)、これは[docs](https://downloads.haskell。 org /〜ghc/latest/docs/html/users_guide/glasgow_exts.html#impredicative-polymorphism)の主張によると、GHCは「極端にフレークなサポート」しか持っていません。最善の回避策は 'newtype'ラッパーです。あるいは、「ImpredicativeTypes」をオンにして、型チェックがタイプチェックされるまで、プログラムの各サブタイトルに型名を追加してください。 – user2407038