2016-07-23 124 views
1

在Python中,我们有一个名为“operator”的内置包,我们可以使用它的任何操作符的函数版本。当使用map和reduce等“函数式编程”功能时,它的使用率很高,并且比使用“lambda”更好。什么是Haskell中的“::”等价函数?

我在Haskell同样的问题:我想用的许多功能组成某处T的用户MAPM,但我不得不使用不那么漂亮的λ:

mapM ((\x->x::String).fromSql.(!!1)) res 

是否有任何相当于liek这样的:

mapM (someFunc(String).fromSql.(!!1)) res 
+4

可以在GHC 8.0中做“id @String”:https://ghc.haskell.org/trac/ghc/wiki/TypeApplication –

+0

'mapM(asTypeOf“”.fromSql。(!! 1)) res' - 除非你有'XOverloadedStrings'。 – Michael

+1

你确定'mapM(fromSql。(!! 1))res'是不够的,或者'mapM((fromSql。(!! 1)):: a - > String)res'? – chepner

回答

1

::String是不是在Python的string(…)意义上的运营商,但类型注释,因此,特殊的语法规则。

你可以,但是,定义功能

asString :: String -> String 
asString x = x 

,然后写

mapM (asString.fromSql.(!!1)) res 

@augustss一次proposed a language extension,将允许(::String)使用,但现在我找不到它。)

+1

!! 1并不意味着头,因为它得到的不是第一个元素。 我不是说身份,我只是想要一个类型提示,以停止获取模糊的类型错误。 – Kamyar

+0

是的,我明白了:如果我们有一个具体类型的身份函数,我们可以像使用类型提示一样使用它。但是除了定义它之外,还有别的方法吗? – Kamyar

+0

这似乎太多的工作,只是给一个类型注释..表达式的类型'mapM ...res'本身可以被指定,并且从这个类型推断可能找到'fromSql'的正确类型。或者可以写'fromSQL :: _ - > String'(带-XPartialTypeSignatures) – user2407038

1

正如chepner所评论的那样,根本没有必要给出任何类型的提示:你需要的只是

mapM (fromSql . (!!1)) res 

......也就是说,假设你实际上是使用结果在某种程度上。 (如果你不使用结果,那么你为什么这么做呢?)

原因是:与Python不同,Haskell有一个合适的Hindley-Milner类型系统,这可以推断任何类型方向和任何上下文。所以,如果你写的只是,例如,

do 
    sqlStrs <- mapM (fromSql . (!!1)) res 
    ... 
    mapM_ putStrLn sqlStr 

那么这足以让编译器推断sqlStrs :: [String]因此fromSql必须加以限制,以产生String


也有一些例外,但只有这些出现与单态的限制(只适用于全球的定义,而不是在一个单子结合的东西,也可以关闭),或使用时例如GADTs,ExistentialQuantification或RankNTypes。

相关问题