【发布时间】:2023-03-04 12:26:01
【问题描述】:
我正在尝试在 Haskell 中嵌入预先计算的数据。那是
catToMap li = Map.fromList $ zip [0..] li
cat1 = catToMap ["aa", "bb", "cc"]
dim = Map.size cat1
我想在类型定义中静态使用dim:
type Network = Grenade.Network
'[Grenade.FullyConnected dim 20, Grenade.FullyConnected 20 1, Grenade.Logit]
'[Grenade.D1 dim, Grenade.D1 20, Grenade.D1 1, Grenade.D1 1]
(从grenade库导入)
但是,上面给出了dim不在范围内的错误。
我也在尝试创建函数
import qualified Numeric.LinearAlgebra.Static as SA
-- | ith standard basis in Rn
stdbasis :: forall n . KnownNat n => Int -> SA.R n
stdbasis i = SA.vector [builder x| x <- [0..n-1]]
where
builder j = if i == j then 1 else 0
但这给了我n不在范围内的错误。
我尝试解决第一个问题是使用模板 Haskell:
catToMap = $(\li -> Map.fromList $ zip [0..] li)
cat1 = $(catToMap ["aa", "bb", "cc"])
dim = $(Map.size cat1)
但它给了我错误
• Couldn't match expected type ‘Q Exp’
with actual type ‘[a0] -> Map.Map Integer a0’
• The lambda expression ‘\ li -> (Map.fromList $ zip ... li)’
has one argument,
but its type ‘Language.Haskell.TH.Lib.ExpQ’ has none
In the expression: \ li -> (Map.fromList $ zip [0 .. ] li)
In the untyped splice: $(\ li -> (Map.fromList $ zip [0 .. ] li))
我想要实现的类似于 C++ 模板:
template <int size> Vector<n>
stdbasis(int i);
【问题讨论】:
-
第二个错误,
n确实不在范围内,你应该使用[0..i-1]。无论如何,我认为这没有多大好处,因为由于惰性编程,常量通常会计算一次。 -
@WillemVanOnsem 如果我每次都手动输入
dim的值,则容易出错且难以更改(例如,如果添加了新类别)。但是在编译时需要该值来构造Network