twitter-bootstrap - Haskell 等式约束

标签 twitter-bootstrap haskell yesod

我正在尝试为 Yesod 构建 bootstrap 3 兼容性。但是,通过创建“renderBootstrap3”函数来做到这一点是不可能的,因为您无法将类添加到输入中。因此,我选择在 Form.Fields 中制作字段的 Bootstrap 版本。 .这个想法是我可以克隆普通字段,但在属性数组中添加一个类声明。以下是相关代码:

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 m a定义为
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和上下文,设置 fieldView f 的字段,两者都只告诉它HandlerSite m是的,简单的事实是你无法弄清楚 m是从那里。就像你有以下情况:
type family F a
type instance F Int = Bool
type instance F Char = Bool

现在尝试传递 F Int在哪里 F Char预计会成功,因为它们都只是 Bool .因此,试图通过 HandlerSite m0在哪里 HandlerSite m预期可能会成功,即使 m不是 m0 !因此,类型检查器不能确定 m0应该与 m 相同,所以你得到一个模棱两可的类型错误。

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

你能删除HandlerSite m来自 injectClass 的类型签名完全用普通类型变量 h 替换它, 说?那应该可以解决您的问题,但我不确定它是否会产生任何新问题。

关于twitter-bootstrap - Haskell 等式约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18605814/

相关文章:

haskell - 在 Haskell 中评估零函数

javascript - Yesod 和 Coffeescript

javascript - float 图像弄乱了 Bootstrap Scrollspy

javascript - Bootstrap 模态加载但无响应

html - Bootstrap4- 用于网格/柔性布局的粘性第一行和第一列

haskell - 安装 yesod 的问题

rest - Haskell Yesod - 执行 POST 请求时浏览器 OPTIONS 请求的 CORS 问题

css - 推特 Bootstrap 网格 : Setting different sizes for mobile

haskell - 返回一个列表,其中包含一对元素,但前提是各个元素的总和是奇数

performance - 优化 Haskell 中的数值数组性能