以下程序类型检查:
{-# 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
如上所述)之外的任何可能的解决方法。
(注意:这不是由单态限制引起的;编译 withNoMonomorphismRestriction
没有帮助。)