函数中的参数顺序和“隐式”参数

时间:2018-12-17 04:51:15

标签: implicit idris function-parameter

我对隐式参数真的很困惑。即在下面的b函数/证明中。

在我试图深入了解的video中,我偶然发现了这一点:我们在{{1}中的{p}之前有隐式String s }绑定定义。

b {p} s

我看到它编译良好。但是我有点希望p处于第二位置:

b : (s : String) -> {p : Every BinChar (unpack s)} -> Nat
b {p} s = fromBinChars p (length s - 1)

甚至(由于b s {p} = fromBinChars p (length s - 1) 是隐式的,并且已经在类型签名中定义/假定了)

p

为什么不是这样?您认为我误解了哪些概念?

这是其余的代码:

b s = fromBinChars p (length s - 1)

1 个答案:

答案 0 :(得分:2)

您的代码包含很多错误。我不知道是由于再次将其键入stackoverflow还是由于错误地从视频中读取了示例。由于视频中的idris版本相当旧,因此您还需要稍微调整代码以使其运行。

这是一个有效的示例:

%default total
data BinChar : Char -> Type where
   O : BinChar '0'
   I : BinChar '1'

data Every : (a -> Type) -> List a -> Type where
   Nil : {P : a -> Type} -> Every P []
   (::) : {P : a -> Type} -> P x
                     -> Every P xs
                     -> Every P (x :: xs)

fromBinChars : Every BinChar xs -> Nat -> Nat
fromBinChars [] k = k
fromBinChars (O :: z) k = fromBinChars z (k `minus` 1)
fromBinChars (I :: z) k = pow 2 k `plus` fromBinChars z (k `minus` 1)

b : (s : String) -> {auto p : Every BinChar (unpack s)} -> Nat
b s {p} = fromBinChars p (length s `minus` 1)

test: b "101" = 5
test = Refl

关于您的问题2) 为什么我不能只忽略隐式参数而写b s = fromBinChars p (length s - 1)?这非常简单-在这种情况下,右侧没有任何东西称为p。您需要在左侧添加p

关于您的问题1) 我想保持参数的顺序会被认为是好的样式,通常也需要这样做。但是idris似乎对待隐式参数有些不同,因此在这种情况下没有关系。但是我不会打赌。在此示例中,我不会假设交换参数背后有真实意图。