函数中的参数顺序和 "implicit" 参数

Parameter order in function and "implicit" paramter

我对隐式参数真的很困惑。即在bfunction/proof下面。

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

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

我看到它编译得很好。但我有点期待 p 排在第二位:

b s {p} = fromBinChars p (length s - 1)

甚至(因为 p 是隐式的并且已经 defined/assumed 在类型签名中)

b s = fromBinChars p (length s - 1)

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

这是剩余的代码:

data BinChar : Char -> Type where
  O : BinChar '0'
  1 : 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 xs (k - 1)
fromBinChars (I :: z) k = pow 2 k + fromBinChars xs (k - 1)  

您的代码包含很多错误。我不知道是因为在Whosebug中再次输入,还是因为误读了视频中的示例。据我所知,视频中的 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 似乎对隐式参数的处理有点不同,所以在这种情况下这无关紧要。但我不会打赌。在这个例子中,我不会假设交换参数背后有真正的意图。