Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Twitter bootstrap 哈斯克尔等式约束_Twitter Bootstrap_Haskell_Yesod - Fatal编程技术网

Twitter bootstrap 哈斯克尔等式约束

Twitter bootstrap 哈斯克尔等式约束,twitter-bootstrap,haskell,yesod,Twitter Bootstrap,Haskell,Yesod,我正在尝试为YesSOD构建Bootstrap3兼容性。然而,通过生成“RenderBotStrap3”函数来实现这一点是不可能的,因为您不能将类添加到输入中。因此,我选择了在Form.fields中创建字段的引导版本。其思想是,我可以克隆普通字段,但可以在attributes数组中添加一个类声明。以下是相关代码: import qualified Yesod.Form.Fields as F injectClass :: (Text -> Text -> [(Text,Text)

我正在尝试为YesSOD构建Bootstrap3兼容性。然而,通过生成“RenderBotStrap3”函数来实现这一点是不可能的,因为您不能将类添加到输入中。因此,我选择了在
Form.fields
中创建字段的引导版本。其思想是,我可以克隆普通字段,但可以在attributes数组中添加一个类声明。以下是相关代码:

import qualified Yesod.Form.Fields as F

injectClass :: (Text -> Text -> [(Text,Text)] -> Either Text a -> Bool -> WidgetT (HandlerSite m) IO ()
           Text -> Text -> [(Text,Text)] -> Either Text a -> Bool -> WidgetT (HandlerSite m) IO ()
injectClass f a b attrs d e = f a b attrs d e

textField :: (Monad m, RenderMessage (HandlerSite m) FormMessage) => Field m Text
textField = addInputClass F.textField

addInputClass :: (Monad m, RenderMessage (HandlerSite m) FormMessage) => Field m a -> Field m a
addInputClass f = f { fieldView = (injectClass $ fieldView f)}
因此,我的目的是采用文本字段的正常版本,并使用记录语法仅修改fieldView方法。此方法应替换为相同的方法,除了添加类属性。这还没有在上面的代码中实现。它可能看起来像:

injectClass f a b attrs d e = f a b (("class", "form-control") : attrs) d e
无论如何,问题是原始代码无法编译。我得到一个等式约束错误:

Could not deduce (HandlerSite m0 ~ HandlerSite m)
from the context (Monad m,
                  RenderMessage (HandlerSite m) FormMessage)
  bound by the type signature for
             addInputClass :: (Monad m,
                               RenderMessage (HandlerSite m) FormMessage) =>
                              Field m a -> Field m a
  at Field/Bootstrap.hs:27:18-95
NB: `HandlerSite' is a type function, and may not be injective
The type variable `m0' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
Expected type: FieldViewFunc m a
  Actual type: Text
               -> Text
               -> [(Text, Text)]
               -> Either Text a
               -> Bool
               -> WidgetT (HandlerSite m0) IO ()
In the `fieldView' field of a record
In the expression: f {fieldView = (injectClass $ fieldView f)}
In an equation for `addInputClass':
    addInputClass f = f {fieldView = (injectClass $ fieldView f)}
请注意,
FieldViewFunc ma
定义为

type FieldViewFunc m a
    = Text -- ^ ID
   -> Text -- ^ Name
   -> [(Text, Text)] -- ^ Attributes
   -> Either Text a -- ^ Either (invalid text) or (legitimate result)
   -> Bool -- ^ Required?
   -> WidgetT (HandlerSite m) IO ()

所以,我离这里不远了。问题是(我认为)它没有重新编码,
injectClass
不会改变monad。但是,这对编译器来说应该是显而易见的。
injectClass
的类型签名对此很清楚。我正在寻找我需要做什么来满足GHC。谢谢您的帮助,如果我能说得更清楚,请告诉我。

啊,类型系列和非注入型

事情是这样的:我们正在尝试进行打字检查

f { fieldView = (injectClass $ fieldView f)}
问题不在于
injectClass
可能会改变
m
是什么。问题是它不知道什么是
m
。它的输入,
fieldView f
和上下文,设置
f
fieldView
字段,两者都只告诉它
HandlerSite m
是什么,简单的事实是,你无法从那里算出
m
是什么。就好像你有以下几点:

type family F a
type instance F Int = Bool
type instance F Char = Bool
现在尝试传递一个
F Int
,其中一个
F Char
将成功,因为它们都是
Bool
。因此,即使
m
不是
m0
,尝试通过一个
HandlerSite m0
,其中一个
HandlerSite m
可能会成功!因此,类型检查器无法确保
m0
m
相同,因此会出现不明确的类型错误

此外,您无法通过手动注释轻松解决歧义,因为您将遇到相同的问题:您将告诉类型检查器什么是
HandlerSite m
,它已经知道了


您是否可以将
HandlerSite m
injectClass
的类型签名中完全删除,并将其替换为普通类型变量
h
?这应该可以解决你的问题,但我不确定它是否会产生新的问题。

有一个更简单的解决方案。您可以重新定义
areq
aopt
以自动添加必要的类:

areqBs3 :: (RenderMessage site FormMessage, HandlerSite m ~ site, MonadHandler m)
     => Field m a
     -> FieldSettings site
     -> Maybe a
     -> AForm m a
areqBs3 a b = areq a (b {fsAttrs = [("class", "form-control")]})

您可以尝试以下类型的签名:
addInputClass::for all m a。(Monad m,RenderMessage(HandlerSite m)FormMessage)=>字段MA->字段MA
。使用语言扩展:
{-#语言范围TypeVariables}