lin*_*r03 4 haskell functional-programming
我写了一个小Haskell程序来找到三角形的区域,主要是为了练习自定义类型,但它在编译时不断抛出以下错误:
areafinder.hs:7:4:
Couldn't match expected type `Triangle' against inferred type `m b'
In a stmt of a 'do' expression: putStr "Base: "
In the expression:
do { putStr "Base: ";
baseStr <- getLine;
putStr "Height: ";
heightStr <- getLine;
.... }
In the definition of `getTriangle':
getTriangle = do { putStr "Base: ";
baseStr <- getLine;
putStr "Height: ";
.... }
Run Code Online (Sandbox Code Playgroud)
我不确定'mb'来自哪里,所以我在这里不知所措.为什么会抛出此错误,我该怎么做才能修复它?这是我的代码:
module Main where
data Triangle = Triangle Double Double -- base, height
getTriangle :: Triangle
getTriangle = do
putStr "Base: "
baseStr <- getLine
putStr "Height: "
heightStr <- getLine
let base = read baseStr :: Double
let height = read heightStr :: Double
Triangle base height
calcTriangle :: Triangle -> Double
calcTriangle (Triangle base height) = base * height
main = putStrLn ("Area = " ++ show (calcTriangle getTriangle))
Run Code Online (Sandbox Code Playgroud)
谢谢.:)
Die*_*Epp 11
该getTriangle函数使用IO,因此您必须将其放在函数签名中.
getTriangle :: IO Triangle
Run Code Online (Sandbox Code Playgroud)
此外,最后一行应该有return,因为它在IO函数内返回一个纯值.
return (Triangle base height)
Run Code Online (Sandbox Code Playgroud)
这里有一些额外的提示:Haskell可以找出base并且height是Double,因为你将它们传递给了Triangle,所以你不需要那样明确地声明它们.您可以使用liftM从Control.Monad模块读取输入并转换为Double一步到位.
import Control.Monad
getTriangle :: IO Triangle
getTriangle = do
putStr "Base: "
base <- liftM read getLine
putStr "Height: "
height <- liftM read getLine
return (Triangle base height)
Run Code Online (Sandbox Code Playgroud)
该main功能似乎也将纯值与IO混合.由于getTriangle是IO,因此无法将其直接传递给calcTriangle.这是一个修改过的main:
main = do tri <- getTriangle
putStrLn ("Area = " ++ show (calcTriangle tri))
Run Code Online (Sandbox Code Playgroud)
作为一个脚注,三角形的区域base * height / 2不是base * height.
最后,更先进的Haskell程序员可能会写getTriangle来讲liftM2,但这只是一个风格问题.我是这样写的:
prompt str = putStr (str ++ ": ") >> liftM read getLine
getTriangle = liftM2 Triangle (prompt "Base") (prompt "Height")
Run Code Online (Sandbox Code Playgroud)