jos*_*iah 0 haskell types arrows functor
我构建类型的方式,我相信这将遵循Functor法则,该法律规定应该有一个身份函数,fmap返回原始函子.
码:
-- apply a style function to a shell prompt functor
-- e.g.
-- bold & fgColor red `style` gitCurrentBranch
style :: (String -> ShellPromptType -> String) -> ShellPromptSegment String
-> ShellPromptType -> ShellPromptSegment String
style f segment = \shType -> (flip f) shType <$> segment
-- this is fine
style' :: (String -> ShellPromptType -> String)
-> (ShellPromptType -> ShellPromptSegment String)
-> ShellPromptType -> ShellPromptSegment String
style' f makeSegment = flip f >>= \g shellType -> fmap g $ makeSegment shellType
-- this apparently is not. Compiler complains that it wants the type (String -> String) -> ShellPromptType -> b
-- for my lambda function there, but it gets (String -> String) -> ShellPromptType -> ShellPromptSegment String
-- instead. I guess 'b' is not allowed to be a functor?
instance Functor ((->) ShellPromptType) where
fmap f makeSegment = ((flip f) :: ShellPromptType -> String -> String)
>>= ((\g shellType -> fmap g $ makeSegment shellType)
:: (String -> String) -> ShellPromptType -> (ShellPromptSegment String))
Run Code Online (Sandbox Code Playgroud)
错误信息:
LambdaLine/Shells/ShellPromptSegment.hs|81 col 30 error| Couldn't match type `ShellPromptType -> String'
|| with `ShellPromptSegment String'
|| Expected type: (String -> String) -> ShellPromptType -> b
|| Actual type: (String -> String)
|| -> ShellPromptType -> ShellPromptSegment String
|| In the second argument of `(>>=)', namely
|| `((\ g shellType -> fmap g $ makeSegment shellType) ::
|| (String -> String)
|| -> ShellPromptType -> (ShellPromptSegment String))'
|| In the expression:
|| ((flip f) :: ShellPromptType -> String -> String)
|| >>=
|| ((\ g shellType -> fmap g $ makeSegment shellType) ::
|| (String -> String)
|| -> ShellPromptType -> (ShellPromptSegment String))
|| In an equation for `fmap':
|| fmap f makeSegment
|| = ((flip f) :: ShellPromptType -> String -> String)
|| >>=
|| ((\ g shellType -> fmap g $ makeSegment shellType) ::
|| (String -> String)
|| -> ShellPromptType -> (ShellPromptSegment String))
LambdaLine/Shells/ShellPromptSegment.hs|81 col 56 error| Couldn't match type `[Char]' with `ShellPromptSegment String'
|| Expected type: ShellPromptSegment String
|| Actual type: a
|| In the return type of a call of `makeSegment'
|| In the second argument of `($)', namely `makeSegment shellType'
|| In the expression: fmap g $ makeSegment shellType
Run Code Online (Sandbox Code Playgroud)
你已经过度专业化了.
仿函数的定义如下:
class Functor f where
fmap :: (a -> b) -> f a -> f b
Run Code Online (Sandbox Code Playgroud)
这个想法是它需要一个正常的功能并将其提升到一些上下文中.但它不止于此:它的想法是它需要任何正常的功能并将其提升到上下文中.对于列表仿函数,fmap
可以使用任何函数并在适当类型的列表上执行它.
你所做的总是返回你的仿函数中的相同类型,这使得它成为仿函数的目的失败,因此Haskell不允许这样做.