函数中的参数顺序和 "implicit" 参数
Parameter order in function and "implicit" paramter
我对隐式参数真的很困惑。即在b
function/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 似乎对隐式参数的处理有点不同,所以在这种情况下这无关紧要。但我不会打赌。在这个例子中,我不会假设交换参数背后有真正的意图。
我对隐式参数真的很困惑。即在b
function/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 似乎对隐式参数的处理有点不同,所以在这种情况下这无关紧要。但我不会打赌。在这个例子中,我不会假设交换参数背后有真正的意图。