haskell 中 RealFloat 的主要函数输入
Main function input for RealFloat in haskell
我正在尝试制作一个接受 2 个 Realfloat 输入并通过此函数的主函数
bmiTell :: (RealFloat a) => a -> a -> String
bmiTell weight height
| bmi <= 18.5 = "You're underweight"
| bmi <= 25.0 = "You're normal"
| bmi <= 30.0 = "You're overweight"
| otherwise = "You're obese"
where bmi = weight / height ^ 2
我的解决方案是,我尝试获取体重和身高并将其传递给 bmiTell 函数
main = do
putStrLn "What's your weight?"
weight <- getLine
putStrLn "What's your height?"
height <- getLine
print (bmiTell( read weight ::Float, read height ::Float))
这就是错误
* No instance for (Show ((Float, Float) -> String))
arising from a use of `print'
(maybe you haven't applied a function to enough arguments?)
* In a stmt of a 'do' block:
print (bmiTell (read weight :: Float, read height :: Float))
In the expression:
do putStrLn "What's your weight?"
weight <- getLine
putStrLn "What's your height?"
height <- getLine
....
In an equation for `main':
main
= do putStrLn "What's your weight?"
weight <- getLine
putStrLn "What's your height?"
....
|
14 | print (bmiTell( read weight ::Float, read height ::Float))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
getbmi.hs:14:12: error:
* No instance for (RealFloat (Float, Float))
arising from a use of `bmiTell'
* In the first argument of `print', namely
`(bmiTell (read weight :: Float, read height :: Float))'
In a stmt of a 'do' block:
print (bmiTell (read weight :: Float, read height :: Float))
In the expression:
do putStrLn "What's your weight?"
weight <- getLine
putStrLn "What's your height?"
height <- getLine
....
|
14 | print (bmiTell( read weight ::Float, read height ::Float))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
我知道 RealFloat 是 Double 或 Float。任何人都可以如何获取 RealFloat 的输入并通过函数传递它。
为简单起见,我将在下面讨论您函数的单态版本,即
bmiTell :: Double -> Double -> String
(对于 RealFloat
,类型 Double
是 usually the only sensible choice。)
如果您定义了
,您的代码将实际运行
bmiTell :: (Double, Double) -> String
bmiTell(weight, height)
| ...
这将是定义多参数函数的“正常方式”,因为大多数其他编程语言都会这样做。在这种情况下 bmiTell (read weight, read height)
会起作用。
您 可以 在 Haskell 中执行此操作,但是我们更喜欢一种不同的样式,它在许多方面是等效的,但提供了一些很好的优势,尽管它经常令人困惑初学者:我们 Curry 大多数多参数函数。
可以很简单地解释:不是在元组中一次提供两个参数,而是提供第一个参数,然后提供下一个。等等。所以,你有函数 bmiTell
。你给它参数 w
,即你写 bmiTell w
。然后你还给它参数h
,所以你写(bmiTell w) h
,解析器允许我们省略括号。
函数因此具有签名 bmiTell :: Double -> SOMETHING
,其中 SOMETHING
必须能够接受另一个参数...然后才给出一个字符串。所以,其实
bmiTell :: Double -> (Double -> String)
这里也是特意选择了解析规则,因此我们实际上可以省略括号。
要使用该函数,你必须,好吧——一个一个地给出两个参数。
bmiTell (read weight) (reight height)
整个节目中:
main :: IO ()
main = do
putStrLn "What's your weight?"
weight <- getLine
putStrLn "What's your height?"
height <- getLine
print (bmiTell (read weight) (read height))
实际上我们喜欢省略更多的括号(我们不是 Lispers!),这可以通过使用方便的空操作 $
运算符来完成:
print $ bmiTell (read weight) (read height)
我正在尝试制作一个接受 2 个 Realfloat 输入并通过此函数的主函数
bmiTell :: (RealFloat a) => a -> a -> String
bmiTell weight height
| bmi <= 18.5 = "You're underweight"
| bmi <= 25.0 = "You're normal"
| bmi <= 30.0 = "You're overweight"
| otherwise = "You're obese"
where bmi = weight / height ^ 2
我的解决方案是,我尝试获取体重和身高并将其传递给 bmiTell 函数
main = do
putStrLn "What's your weight?"
weight <- getLine
putStrLn "What's your height?"
height <- getLine
print (bmiTell( read weight ::Float, read height ::Float))
这就是错误
* No instance for (Show ((Float, Float) -> String))
arising from a use of `print'
(maybe you haven't applied a function to enough arguments?)
* In a stmt of a 'do' block:
print (bmiTell (read weight :: Float, read height :: Float))
In the expression:
do putStrLn "What's your weight?"
weight <- getLine
putStrLn "What's your height?"
height <- getLine
....
In an equation for `main':
main
= do putStrLn "What's your weight?"
weight <- getLine
putStrLn "What's your height?"
....
|
14 | print (bmiTell( read weight ::Float, read height ::Float))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
getbmi.hs:14:12: error:
* No instance for (RealFloat (Float, Float))
arising from a use of `bmiTell'
* In the first argument of `print', namely
`(bmiTell (read weight :: Float, read height :: Float))'
In a stmt of a 'do' block:
print (bmiTell (read weight :: Float, read height :: Float))
In the expression:
do putStrLn "What's your weight?"
weight <- getLine
putStrLn "What's your height?"
height <- getLine
....
|
14 | print (bmiTell( read weight ::Float, read height ::Float))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
我知道 RealFloat 是 Double 或 Float。任何人都可以如何获取 RealFloat 的输入并通过函数传递它。
为简单起见,我将在下面讨论您函数的单态版本,即
bmiTell :: Double -> Double -> String
(对于 RealFloat
,类型 Double
是 usually the only sensible choice。)
如果您定义了
,您的代码将实际运行bmiTell :: (Double, Double) -> String
bmiTell(weight, height)
| ...
这将是定义多参数函数的“正常方式”,因为大多数其他编程语言都会这样做。在这种情况下 bmiTell (read weight, read height)
会起作用。
您 可以 在 Haskell 中执行此操作,但是我们更喜欢一种不同的样式,它在许多方面是等效的,但提供了一些很好的优势,尽管它经常令人困惑初学者:我们 Curry 大多数多参数函数。
可以很简单地解释:不是在元组中一次提供两个参数,而是提供第一个参数,然后提供下一个。等等。所以,你有函数 bmiTell
。你给它参数 w
,即你写 bmiTell w
。然后你还给它参数h
,所以你写(bmiTell w) h
,解析器允许我们省略括号。
函数因此具有签名 bmiTell :: Double -> SOMETHING
,其中 SOMETHING
必须能够接受另一个参数...然后才给出一个字符串。所以,其实
bmiTell :: Double -> (Double -> String)
这里也是特意选择了解析规则,因此我们实际上可以省略括号。
要使用该函数,你必须,好吧——一个一个地给出两个参数。
bmiTell (read weight) (reight height)
整个节目中:
main :: IO ()
main = do
putStrLn "What's your weight?"
weight <- getLine
putStrLn "What's your height?"
height <- getLine
print (bmiTell (read weight) (read height))
实际上我们喜欢省略更多的括号(我们不是 Lispers!),这可以通过使用方便的空操作 $
运算符来完成:
print $ bmiTell (read weight) (read height)