该表达式预计具有类型单位

时间:2015-09-22 17:22:05

标签: f# f#-interactive unit-type

我有以下代码。在这一行

 if min<=0  then     min <- List.nth list i |>ignore

我有2个错误。    首先在0

 This expression was expected to have type
    unit    
but here has type
    int

然后在i

This expression was expected to have type
    unit    
but here has type
    int

*      我也看过this并尝试忽略,但它不起作用

let replace touple2=
   let first  (a,_,_,_,_)=a
   let second (_,b,_,_,_)=b
   let third  (_,_,c,_,_)=c
   let forth  (_,_,_,d,_)=d
   let fifth  (_,_,_,_,e)=e
   let sortedlist list= List.sort(list)

   let GetMin list=
        list |> List.rev |> List.head
        let mutable min=list.Head
        let mutable i=1
        for i in list do     
            if min<=0  then     min <- List.nth list i |>ignore

        min 

   let GetMax list=list |> List.rev |> List.head

   let A=first  touple2
   let B=second touple2
   let C=third  touple2
   let D=forth  touple2
   let E=fifth  touple2
   let mylist=[A;B;C;D;E]
   let L=sortedlist mylist

   let m1=GetMax L
   printfn "%d"  m1

let touple3= 14,6,18,76,76
replace touple3

3 个答案:

答案 0 :(得分:5)

您不需要ignore - 如果您正在使用作业,则会返回unit,因此您没有任何必须忽略的返回值:

if min <= 0 then min <- List.nth list I

那就是说,这不是很实用的方法。因此,查看一些基本的F#书或观看一些演讲可能会帮助您开始使用更多F#风格的语言。

答案 1 :(得分:3)

你只需要括号就可以让编译器明白你的意图:

if min <= 0 then (min <- List.nth list i) |> ignore

如果没有F#中的else,则是:

的简写
if condition then doSomething else ()

这意味着doSomething块内的任何内容必须是unit类型的结果。由于F#中的赋值是一个表达式,因此您的代码返回min,即int值。这解释了您的第一个错误。

上面发生的原因是,没有括号,管道运算符使用最后一个参数os List.nthi作为ignore的参数

答案 2 :(得分:0)

第一个问题是list |> List.rev |> List.head导致编译器推断listunit类型。如果删除该行(因为它无意义,F#列表是不可变的,因此您计算的是未使用的值),list被正确推断为类型int list,这会产生第一个错误离开(如果我们也使用List.head list代替list.Head来快速进行类型推断)。

然后,这一行if min<=0 then min <- List.nth list i |>ignore出现第二个错误,这是有意义的,因为对可变变量的赋值不应该留给|> ignore。所以让我们摆脱它,修复弃用警告并添加一些格式......这个编译:

let replace touple2 =
   let first  (a,_,_,_,_) = a
   let second (_,b,_,_,_) = b
   let third  (_,_,c,_,_) = c
   let forth  (_,_,_,d,_) = d
   let fifth  (_,_,_,_,e) = e
   let sortedlist list= List.sort(list)

   let GetMin list=
        let mutable min = List.head list
        let mutable i = 1
        for i in list do     
            if min <= 0 then min <- List.item i list

        min 

   let GetMax list = list |> List.rev |> List.head

   let A = first  touple2
   let B = second touple2
   let C = third  touple2
   let D = forth  touple2
   let E = fifth  touple2
   let mylist = [A;B;C;D;E]
   let L = sortedlist mylist

   let m1 = GetMax L
   printfn "%d" m1

let touple3 = 14,6,18,76,76
replace touple3

尽管如此,它并不像F#-ish那样。怎么样(包括疯狂猜测你想要达到的目标):

let printMinMax (a, b, c, d, e) =

    let minPositive sortedList = 
        sortedList |> List.fold (fun m e -> if m <= 0 then e else m) sortedList.Head

    let max sortedList = sortedList |> List.last

    let sortedList = [ a; b; c; d; e ] |> List.sort

    printfn "min %d, max %d" (minPositive sortedList) (max sortedList)

let t1 = 14, 6, 18, 76, 76
printMinMax t1

let t2 = -1, -5, 5, 16, 12
printMinMax t2

这可以进一步改进,但我担心与原版的联系变得更不明显(并且预计至少会有一个正值):

let minMax (a, b, c, d, e) =
    let l = [ a; b; c; d; e ] |> List.sortDescending
    let positiveMin = l |> List.findBack ((<) 0)
    let max = l.Head
    positiveMin, max

let t1 = 14, 6, 18, 76, 76
let t2 = -1, -5, 5, 16, 12

let test t =
    let min, max = minMax t
    printfn "min (positive) %d, max %d" min max

test t1
test t2