haskell 整数->双精度->字符串

n8ghc7c1  于 2022-11-14  发布在  其他
关注(0)|答案(3)|浏览(180)

我不能肯定,我明白这一点:

f :: Integer -> Double -> String -> String
f a d s = undefined

f的潜在主体在这里会是什么呢?我对这个以前从未遇到过的新语法感到困惑。

**EDIT:**那么,既然aInteger,而dDouble,那么方法体是否可以这样写,即根据类型返回String?就像比较一样。
巨蟒:

def f(a: int, d: float, s: str) -> str:
  if(s == "Is Integer less than Double"):
    if(a < d):
      return "Yes, it is."
    else:
      return "No, it isn't"

"如何在Haskell做同样的事?"

p5cysglq

p5cysglq1#

你可以翻译你的Python代码,把语法结构几乎逐字地Map到Haskell。

  • 你不需要return(因为在Haskell中你总是直接指定函数返回什么,并且只需要额外的语法来管理一元副作用--而这个函数没有)。
  • 另一方面,你 * 确实 * 需要在每个if语句中有一个else,因为不像在Python中,你不能 * 不返回任何东西 *(好吧,可以说你在Python中也不能这样做,如果你没有显式地返回其他东西,它只是默认返回None)。
  • 你不能直接在两个不同类型的变量上使用<,与Python不同,Haskell从不自动进行类型转换,但是你可以显式地使用fromIntegral

所以,

f a d s =
   if(s == "Is Integer less than Double")
     then if(fromInteger a < d)
       then "Yes, it is."
       else "No, it isn't"
     else {- ...whatever should happen in this case -}

Haskellers倾向于不使用if结构,而是使用 guards 作为条件,即:

f a d s
 | s == "Is Integer less than Double"
    = if(fromInteger a < d)
       then "Yes, it is."
       else "No, it isn't"
 | otherwise = {- ...whatever should happen in this case -}

这实际上也允许您省略显式回退情况,尽管编译器随后会警告不完全匹配。
无论如何这还是不地道的:Haskellers避免绑定一个函数参数来检查它是否相等,相反,你只需要对你要比较的值进行 pattern match

f a d "Is Integer less than Double"
    = if(fromInteger a < d)
       then "Yes, it is."
       else "No, it isn't"
f a d s = {- ...whatever should happen in this case -}

现在,您实际上可以将guards用于原来的内部if

f a d "Is Integer less than Double"
 | fromInteger a < d
              = "Yes, it is."
 | otherwise  = "No, it isn't"
f a d s = {- ...whatever should happen in this case -}

如果你真的不想处理任何其他字符串的情况,那么你应该把它作为一个 failure case,也可以通过类型签名来表达:

f :: Integer -> Double -> String -> Maybe String
f a d "Is Integer less than Double"
 | fromInteger a < d
              = Just "Yes, it is."
 | otherwise  = Just "No, it isn't"
f _ _ _ = Nothing
dw1jzc5e

dw1jzc5e2#

那么,既然aInteger,而dDouble,那么方法的主体是否可以这样写,即根据类型返回String?就像比较一样。
是的,但是有一个小小的警告。**(<) :: Ord a => a -> a -> Bool要求两个操作数具有相同的类型,所以我们需要首先将Integer转换为一个双精度型,我们可以使用fromInteger :: Num a => Integer -> a**将其转换为Num类型类中的任何类型。
我们可以使用 guards 实现此功能,如下所示:

f :: Integer -> Double -> String -> String
f a d "Is Integer less than Double"
  | fromInteger a < d = "Yes, it is."
  | otherwise = "No, it isn't"

但是函数不是 total,只有当第三个参数是"Is Integer less than Double"时,它才会比较这两个参数。Haskell的程序员倾向于选择对每个 * 可能 * 的输入都返回值的函数,因为这样他们就不必担心传递某些输入。

nc1teljy

nc1teljy3#

Integer -> Double -> String -> String

函数的参数列表的这种表示方式就是“函数式编程”如何看待函数。
在非函数式语言中,我们通常会看到这样的情况:

String (Integer, Double, String) // C-like prefix types
(Integer, Double, String): String // Python like postfix type

但事情是这样的:函数式语言使用这种形式,因为您可以创建在非函数式语言中不可能实现的部分函数(无需特别设计)
这意味着所有这些都是该签名的有效函数

result1 = f i d s ;;( (Integer->Double->String)->String)

g = f i ;;( (Integer)->(Double->String->String) )
result2 = g d s 

h = f i d ;;( (Integer->Double)->(String->String) )
result3 = h s

在您提供所有必需的参数之前,您将获得由您提供的参数组成的部分函数。

相关问题