考虑以下代码
{-# 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工作而不必为消除歧义定义命名函数?
答案 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!="")'
添加类型签名应强制编译器选择正确的版本。