F#错误:表达式应具有类型单位

F#错误:表达式应具有类型单位,f#,functional-programming,f#-interactive,f#-3.0,F#,Functional Programming,F# Interactive,F# 3.0,我正试着用F#构建一个计算器。所以,我从用户那里获取关于要执行的操作的输入。对于输入6,它应该显示用于科学操作的菜单,然而,它说表达式应该有类型unit,但有类型float。同样在scientificFun()函数中,最后一行说,“表达式应该有float,但这里有unit”。我不知道这是什么意思。这件事已经纠缠了好几个小时了。任何帮助都将不胜感激。谢谢**或粗体线显示发生错误的位置 open System let mutable ok = true while ok do Console.Wr

我正试着用F#构建一个计算器。所以,我从用户那里获取关于要执行的操作的输入。对于输入6,它应该显示用于科学操作的菜单,然而,它说表达式应该有类型unit,但有类型float。同样在scientificFun()函数中,最后一行说,“表达式应该有float,但这里有unit”。我不知道这是什么意思。这件事已经纠缠了好几个小时了。任何帮助都将不胜感激。谢谢**或粗体线显示发生错误的位置

open System

let mutable ok = true
while ok do
Console.WriteLine("Choose a operation:\n1.Addition\n2.Substraction\n3.Multiplication\n4.Division\n5.Modulo\n6.Scientific")
let input= Console.ReadLine()  

let add() = 
    Console.WriteLine("Ok, how many numbers?")
    let mutable count = int32(Console.ReadLine())
    let numberArray = Array.create count 0.0
    for i in 0 .. numberArray.Length - 1 do
        let no = float(Console.ReadLine())
        Array.set numberArray i no    
    Array.sum numberArray

let expo() =
    Console.WriteLine("Enter the base")
    let getBase = Console.ReadLine()
    Console.WriteLine("Enter the exponent")
    let getExponent = Console.ReadLine()
    float(getBase) ** float(getExponent)

let sqRoot() = 
    Console.WriteLine("Enter a number")
    let no = float(Console.ReadLine())        
    Math.Sqrt no

let rec fact (n:float) =
    if n < 1.0 then 1.0
    else n * fact (n - 1.0)

let factorial() = 
    Console.WriteLine("Enter a number")
    let no = float(Console.ReadLine())
    fact(no)


let Trigsin() = 
    Console.WriteLine("Enter an angle")
    let angle = float(Console.ReadLine())
    Math.Sin angle
let Trigcos() =
    Console.WriteLine("Enter an angle")
    let angle = float(Console.ReadLine())
    Math.Cos angle
let Trigtan() =
    Console.WriteLine("Enter an angle")
    let angle = float(Console.ReadLine())
    Math.Tan angle

let logicalAnd() =
    Console.WriteLine("Enter first number")
    let first = int32(Console.ReadLine())
    Console.WriteLine("Enter second number")
    let second = int32(Console.ReadLine())
    float(first &&& second) 
let logicalOr() =
    Console.WriteLine("Enter first number")
    let first = int(Console.ReadLine())
    Console.WriteLine("Enter second number")
    let second = int(Console.ReadLine())
    float(first ||| second)
let logicalNot()=
    Console.WriteLine("Enter a number")
    let first = int32(Console.ReadLine())
    float(~~~first)
let sub x y = x - y 
let mul x y = x * y
let div x y = x / y
let MOD x y = x % y

let scientificFun() = 
    printfn("1.Exponential\n2.Square Root\n3.Factorial\n4.sin()\n5.cos()\n6.tan()\n7.AND\n8.OR\n9.NOT")
    let scientificInput = Console.ReadLine()
    match scientificInput with
    |"1" -> expo()
    |"2" -> sqRoot()
    |"3" -> factorial()
    |"4" -> Trigsin()
    |"5" -> Trigcos()
    |"6" -> Trigtan()
    |"7" -> logicalAnd()
    |"8" -> logicalOr()
    |"9" -> logicalNot()
    | _ -> **printfn("Choose between 1 - 9")**



match input with
| "1" -> printfn("The Result is: %f") (add())
//| "2" -> printfn("The Result is: %f") (sub A B)
//| "3" -> printfn("The Result is: %f") (mul A B)
///| "4" -> printfn("The Result is: %f") (div A B)
//| "5" -> printfn("The Result is: %f") (MOD A B)
| "6" -> **scientificFun()**
| _-> printfn("Choose between 1 and 6")
Console.WriteLine("Would you like to use the calculator again? y/n")
let ans = Console.ReadLine()
if ans = "n" then
    ok <- false
else Console.Clear()
开放系统
设可变ok=true
虽然可以做
Console.WriteLine(“选择一个操作:\n1.加法\n2.减法\n3.乘法\n4.除法\n5.模\n6.科学”)
让输入=Console.ReadLine()
让我们添加()
Console.WriteLine(“好的,有多少个数字?”)
让可变计数=int32(Console.ReadLine())
让numberraray=Array.create计数为0.0
因为我在0。。numberArray.Length-1do
let no=float(Console.ReadLine())
Array.set numberray i no
Array.sum numberray
让世博会=
Console.WriteLine(“输入基”)
让getBase=Console.ReadLine()
Console.WriteLine(“输入指数”)
让getExponent=Console.ReadLine()
浮点(getBase)**浮点(getExponent)
设sqRoot()
Console.WriteLine(“输入数字”)
let no=float(Console.ReadLine())
数学
让记录事实(n:浮动)=
如果n<1.0,则为1.0
else n*事实(n-1.0)
设阶乘()
Console.WriteLine(“输入数字”)
let no=float(Console.ReadLine())
事实(否)
让Trigsin()
Console.WriteLine(“输入角度”)
让角度=浮动(Console.ReadLine())
数学,正弦角
让Trigcos()=
Console.WriteLine(“输入角度”)
让角度=浮动(Console.ReadLine())
数学角
让Trigtan()=
Console.WriteLine(“输入角度”)
让角度=浮动(Console.ReadLine())
数学,谭角
let logicalAnd()=
Console.WriteLine(“输入第一个数字”)
让first=int32(Console.ReadLine())
Console.WriteLine(“输入第二个数字”)
设second=int32(Console.ReadLine())
浮动(第一和第二)
let logicalOr()=
Console.WriteLine(“输入第一个数字”)
让first=int(Console.ReadLine())
Console.WriteLine(“输入第二个数字”)
设second=int(Console.ReadLine())
浮动(第一| | |第二)
let logicalNot()=
Console.WriteLine(“输入数字”)
让first=int32(Console.ReadLine())
浮动(~~~第一个)
设subxy=x-y
设mul x y=x*y
设div x y=x/y
设MOD x y=x%y
让科学变得有趣
printfn(“1.指数\n2.平方根\n3.阶乘\n4.sin()\n5.cos()\n6.tan()\n7.和\n8.或\n9.NOT”)
让scientificInput=Console.ReadLine()
将科学的输入与
|“1”->世博会()
|“2”->sqRoot()
|“3”->阶乘()
|“4”->Trigsin()
|“5”->Trigcos()
|“6”->Trigtan()
|“7”->logicalAnd()
|“8”->logicalOr()
|“9”->logicalNot()
|打印fn(“在1-9之间选择”)**
匹配输入
|“1”->printfn(“结果是:%f”)(add())
//|“2”->printfn(“结果为:%f”)(子A B)
//|“3”->printfn(“结果为:%f”)(mul A B)
///|“4”->printfn(“结果是:%f”)(分区A和分区B)
//|“5”->printfn(“结果是:%f”)(MOD A B)
|“6”->**科学乐趣()**
|->printfn(“在1和6之间选择”)
Console.WriteLine(“您想再次使用计算器吗?是/否”)
让ans=Console.ReadLine()
如果ans=“n”,则
好啊
表达式应该有float,但这里有unit

这是来自编译器的一条非常重要的消息,您应该尝试理解它为什么这么说,以及它的含义。简单来说,函数将值从一个域映射到另一个域

如果您有一个函数,例如:

let makeStr (x:int) =
    string x
它的签名将告诉您它的输入和输出类型:
valmakestr:x:int->string
。在本例中,它接受一个int并将其作为字符串返回。因此,这是可行的:
makeStr 10
,但这不会
makeStr 10。
,它将失败,并显示以下消息:

错误FS0001:此表达式应具有类型 int,但这里有类型 浮动

在您的特定情况下,您可以检查
scientificFun()
的签名。VSCode和VS2015都将向您展示它是
val scientificFun:(单位->浮动)
。这是一个不接受输入(单位)并返回浮点的函数。但是,在选项中,您有
->printfn(“在1-9之间选择”)
printfn
打印到控制台,但不返回值,或者更确切地说,它返回()(单位),这表明它有副作用,例如打印到控制台。不能从一个分支返回浮点值,也不能从另一个分支返回其他值。有几种方法可以解决这个问题,其中一种是@Funk建议的,基本上将返回值包装在选项类型中,这可能是最好的选项;^)。但在这种情况下,让我们稍微作弊一下,以一种快速而肮脏的方式修复您的函数:

将匹配表达式的最后一行更改为:
||->printfn(“在1-9之间选择”);0.
在这里,通配符变成了一个复合表达式,它打印出来,但最终返回0.,这是一个浮点,F#编译器很高兴

然后你仍然需要在最后一场比赛中修正选项6。如果你看上面,你可以看到所有其他分支打印到控制台,所以应该返回单位,但scientificFun的签名会告诉你它返回浮点,那么它是哪一个?只需将分支更改为与所有其他表达式类似:
|“6”->printfn(“结果是:%f”)请发布一个。模式匹配的所有返回值必须是相同的类型。如果您匹配
scientificInput
所有函数都返回
float
,除了
printfn
,它返回
unit
。谢谢@Funk..您能告诉我如何实现这一点吗。?。Af
let rec scientificFun() = 
    printfn("1.Exponential\n2.Square Root\n3.Factorial\n4.sin()\n5.cos()\n6.tan()\n7.AND\n8.OR\n9.NOT")
    let scientificInput = Console.ReadLine()
    match scientificInput with
    |"1" -> expo()
    |"2" -> sqRoot()
    |"3" -> factorial()
    |"4" -> Trigsin()
    |"5" -> Trigcos()
    |"6" -> Trigtan()
    |"7" -> logicalAnd()
    |"8" -> logicalOr()
    |"9" -> logicalNot()
    | _ -> scientificFun()