代码之家  ›  专栏  ›  技术社区  ›  Greg S

haskell:读取和键入签名

  •  6
  • Greg S  · 技术社区  · 15 年前

    read is defined in the prelude as

    read::(read a)=>string->a
    < /代码> 
    
    

    并且可以用作例如read“1”::int

    现在是一个函数

    readone::(read a)=>[string]->(a,[string])
    readone(x:xs)=(读取x,xs)
    < /代码> 
    
    

    与错误中的readone[“1”,“foo”]results(as expected)一起使用

    <代码> 约束中的类型变量“a”不明确:
    在1:0-18使用“readone”时产生的“read a”
    可能修复:添加修复这些类型变量的类型签名 < /代码>

    readone[“1”,“foo”]:int不起作用,while

    readonent::[string]->(int,[string])
    readonent=读数
    < /代码> 
    
    

    工作很好:

    >readonent[“1”,“foo”]
    (1,[ Foo ])
    < /代码> 
    
    

    那么:如何在不定义新函数的情况下将类型签名添加到readone

    readOne :: (Read a) => [String] -> (a, [String])
    readOne (x:xs) = (read x,xs)
    

    用于readOne ["1","foo"]错误中的结果(如预期)

    约束中的类型变量“a”不明确:
    在1:0-18使用“readone”产生的“read a”
    可能修复:添加修复这些类型变量的类型签名

    但是readOne ["1","foo"] :: Int不工作,而

    readOneInt :: [String] -> (Int, [String])
    readOneInt = readOne
    

    工作很好:

    > readOneInt ["1", "foo"]
    (1,["foo"])
    

    那么:我怎样才能在readOne不定义新的函数readOneInt?

    1 回复  |  直到 15 年前
        1
  •  9
  •   sepp2k    15 年前

    readOne ["1","foo"] :: Int 不起作用是因为 readOne 无法返回 Int ,它始终返回一个元组,其第二个元素是 [String] . readOne ["1", "foo"] :: (Int, [String]) 会工作。

    请注意,如果无法推断类型,则只需指定该类型。如果你使用 读写器 在需要成为 int ,你可以使用 读写器 没有类型批注。例子:

    let inc (i, strs) = (i + 1, strs) in
    inc (readOne ["1", "foo"])
    -- (2, ["foo"])