lambdas或函数组合中的任何消歧方式(没有中间函数)?

时间:2018-04-10 08:45:52

标签: haskell

考虑以下代码

{-# LANGUAGE DuplicateRecordFields #-}
data Human = Human {name :: String } deriving (Show , Eq)
data Dog = Dog {name :: String } deriving (Show , Eq)

humans = [Human "bob" , Human "john", Human "paul"]

-- Working
humanName h = name (h :: Human)
fh = filter ( (=="bob").humanName ) humans  
fh' = filter (\h -> (humanName h )=="bob"  ) humans  

-- Ambigous, not compiling
fh2 = filter ( (=="bob").name ) humans
-- Ambigous, not compiling
fh3 = filter (\h -> (name h )=="bob"  ) humans

-- Not compiling, I don't know if it's an error syntax or if this is impossible
fh4 = filter (\h -> (name h)=="bob" (h :: Human) ) humans

有没有办法让fh2,fh3或fh4工作而不必为消除歧义定义命名函数?

3 个答案:

答案 0 :(得分:5)

由于name是重复的记录字段,您需要指定它应用于哪种类型:

fh3 = filter (\h -> (name (h::Human))=="bob") humans

有关详细信息,请参阅DuplicateRecordFields

修改

否则,在处理重复的记录字段时,我想按照以下步骤进行操作。

{-# LANGUAGE DuplicateRecordFields #-}
data Human = Human {_name :: String } deriving (Show , Eq)
data Dog = Dog {_name :: String } deriving (Show , Eq)

class HasName a where 
    name :: a -> String

instance HasName Human where
    name = _name

instance HasName Dog where
    name = _name

然后你可以做

filter (\h -> (name h == "bob")) humans

答案 1 :(得分:2)

添加到@StéphaneLaurent的答案,使用TypeApplication可以帮助实现无点样式:

{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE TypeApplications #-} 
data Human = Human {_name :: String } deriving (Show , Eq)
data Dog = Dog {_name :: String } deriving (Show , Eq)

class HasName a where 
    name :: a -> String

instance HasName Human where
    name = _name

instance HasName Dog where
    name = _name

humans = [Human "bob" , Human "john", Human "paul"]

-- Now you can write it in pointfree style:
fh2 = filter ((=="Bob") . name @Human) humans
--                             ^^^^^^ This is a type argument!

答案 2 :(得分:1)

为什么不为所有这些功能添加类型签名?喜欢:

jq 'select(.value!="")'

添加类型签名应强制编译器选择正确的版本。