【发布时间】:2017-08-08 08:29:21
【问题描述】:
以下程序类型检查:
{-# 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 没有帮助。)
【问题讨论】:
标签: haskell type-mismatch type-systems automatic-differentiation