【问题标题】:Idris: function works with Nat parameter and fails type checking with Integer parameterIdris:函数使用 Nat 参数,但使用 Integer 参数的类型检查失败
【发布时间】:2016-06-30 10:10:28
【问题描述】:

我是伊德里斯的新手。我正在试验类型,我的任务是制作一个“洋葱”:一个接受两个参数的函数:一个数字和其他任何内容,并将任何内容放入 List 中嵌套这么多次。

例如,mkOnion 3 "Hello World" 的结果应该是 [[["Hello World"]]]。 我做了这样一个函数,这是我的代码:

onionListType : Nat -> Type -> Type
onionListType Z b = b
onionListType (S a) b = onionListType a (List b)

mkOnionList : (x : Nat) -> y -> onionListType x y 
mkOnionList Z a = a
mkOnionList (S n) a = mkOnionList n [a]

prn : (Show a) => a -> IO (); 
prn a = putStrLn $ show a;

main : IO()
main = do
    prn $ mkOnionList 3 4
    prn $ mkOnionList 2 'a'
    prn $ mkOnionList 5 "Hello"
    prn $ mkOnionList 0 3.14

程序工作的结果:

[[[4]]]  
[['a']]  
[[[[["Hello"]]]]]  
3.14

这正是我所需要的。 但是当我这样做时,像这样将 Nat 更改为 Integer

onionListTypeI : Integer -> Type -> Type
onionListTypeI 0 b = b
onionListTypeI a b = onionListTypeI (a-1) (List b)

mkOnionListI : (x : Integer) -> y -> onionListTypeI x y 
mkOnionListI 0 a = a
mkOnionListI n a = mkOnionListI (n-1) [a]

我收到一个错误:

When checking right hand side of mkOnionListI with expected type   
    onionListTypeI 0 y

Type mismatch between  
    y (Type of a) and   
    onionListTypeI 0 y (Expected type)

为什么类型检查会失败?

我认为这是因为Integer 可以取负值,而Type 在负值的情况下无法计算。如果我是对的,编译器是怎么理解的?

【问题讨论】:

    标签: idris partial-functions


    【解决方案1】:

    你是对的,类型无法计算。但那是因为onionListTypeI 不是全部。您可以在 REPL 中检查这一点

    *test> :total onionListTypeI
    Main.onionListTypeI is possibly not total due to recursive path:
        Main.onionListTypeI, Main.onionListTypeI
    

    (或者更好,在源代码中要求%default total,这会引发错误。)

    由于类型构造函数不是全部,编译器不会将onionListTypeI 0 y 规范化为y。这不是全部,因为onionListTypeI a b = onionListTypeI (a-1) (List b) 的情况。编译器只知道从Integer 中减去 1 会得到Integer,但不知道确切的数字(与使用Nat 时不同)。这是因为IntegerIntDouble 和各种Bits 的算术是使用prim__subBigInt 等主要函数定义的。如果这些函数不会是盲目的,那么编译器应该会遇到负值问题,就像你假设的那样。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-24
      • 2021-12-09
      • 1970-01-01
      • 2022-06-11
      • 1970-01-01
      • 2012-02-08
      相关资源
      最近更新 更多