以下FooA
显式使用(#)
作为queryP
和{-# LANGUAGE RankNTypes, ScopedTypeVariables #-}
module Foo where
class Foo a where
newtype FooParser a = FooParser { (#) :: FooA -> (a, FooA) }
queryP :: (FooA -> a) -> FooParser a
queryP f = FooParser $ \(b :: FooA) -> (f b, b)
data FooA = FooA Int
instance Foo FooA where
中的类型按预期编译:
FooParser
但是,当我尝试使用类型queryP
来定义Foo
和{-# LANGUAGE RankNTypes, ScopedTypeVariables #-}
module Foo where
class Foo a where
newtype FooParser a = FooParser { (#) :: Foo b => b -> (a, b) }
queryP :: Foo b => (b -> a) -> FooParser a
queryP f = FooParser $ \(b :: Foo b => b) -> (f b, b)
时,如下所示:
Foo.hs:11:52:
Could not deduce (b ~ b1)
from the context (Foo b)
bound by the type signature for
queryP :: Foo b => (b -> a) -> FooParser a
at Foo.hs:10:11-42
or from (Foo b1)
bound by a type expected by the context: Foo b1 => b1 -> (a, b1)
at Foo.hs:11:12-53
‘b’ is a rigid type variable bound by
the type signature for queryP :: Foo b => (b -> a) -> FooParser a
at Foo.hs:10:11
‘b1’ is a rigid type variable bound by
a type expected by the context: Foo b1 => b1 -> (a, b1)
at Foo.hs:11:12
Relevant bindings include
b :: Foo b => b (bound at Foo.hs:11:26)
f :: b -> a (bound at Foo.hs:11:8)
queryP :: (b -> a) -> FooParser a (bound at Foo.hs:11:1)
In the expression: b
In the expression: (f b, b)
我得到了一个无法推断的错误:
b
如何指定queryP
中lambda函数中的Foo
与f
的第一个参数中的类型 $('.date-picker').hover(function(){
if(!$(this).hasClass('hasDatepicker')){
$(this).addClass('hasDatepicker');
$(this).datepicker();
}
});
的实例相同?< / p>
答案 0 :(得分:5)
在类型定义
中newtype FooParser a = FooParser { (#) :: Foo b => b -> (a, b) }
类型变量b
通常以更高级别的类型绑定;即新引入的选择器函数(#)
的类型是
*Foo> :t (#)
(#) :: Foo b => FooParser a -> b -> (a, b)
但这意味着当您构建FooParser a
时,传递给构造函数的函数必须在b -> (a, b)
处键入{strong>任何选择的b
(如只要Foo b
持有):
*Foo> :t FooParser
FooParser :: (forall b. Foo b => b -> (a, b)) -> FooParser a
但是,在queryP
中,b -> a
为某些选择b
提供了b
类型的函数(Foo b
由b ~ b1
选择调用者,queryP
将保留的唯一限制。
因此,如果我设置f :: b1 -> a
并调用forall b. (Foo b) => b -> (a, b)
,则表示我向您传递了FooParser
类型的函数。然后,您必须向我返回类型为f
的函数(包含在构造函数b
中)。
您不能仅为此目的使用b1
,因为b ~ b2
除了Foo
之外的任何选择(例如forall b. (Foo b) => b -> (a, b)
)都不会是正确的类型。
在目前的形式中,您基本上只能使用queryP
类中的函数和参数化足够多态的函数来构造queryP :: (forall b. Foo b => (b -> a)) -> FooParser a
queryP f = FooParser $ \b -> (f b, b)
函数。根据您的目的,您可以
FooParser
以使其具有多态功能:b
{-# LANGUAGE ExistentialQuantification #-}
data FooParser a = forall b. Foo b => FooParser { (#) :: b -> (a, b) }
,以便def autocomplete_property_address
properties = Property.address_theme_joint_table(current_user.company.theme_name,"%#{params[:term]}%")
#render properties
render :json => properties.map{ |property|{:id => property.id, :address => property.address}}
end
存在受限:<%= text_field_tag :search, params[:search], class: "search-query", placeholder: "Address search", type: "search", data: {autocomplete: autocomplete_property_address_properties_path}, :id_element => '', :update_elements => {} %>
请注意,这两项变化意味着(并暗示)非常不同的事情。