这是 3 种类型的多态函数:
:t (.)
(.) :: (b -> c) -> (a -> b) -> a -> c
Run Code Online (Sandbox Code Playgroud)
这里是一个非多态函数:
:t Data.Char.digitToInt
Data.Char.digitToInt :: Char -> Int
Run Code Online (Sandbox Code Playgroud)
如果我们将前者应用于后者,我们会得到一个多态的函数:1 类型:
:t (.) Data.Char.digitToInt
(.) Data.Char.digitToInt :: (a -> Char) -> a -> Int
Run Code Online (Sandbox Code Playgroud)
这意味着它(.)是“实例化的”(我不确定这是正确的术语;作为 C++ 程序员,我会这样称呼它)b === Char和c === Int,因此(.)被应用的的签名digitToInt如下
(Char -> Int) -> (a -> Char) -> a -> Int
Run Code Online (Sandbox Code Playgroud)
我的问题是:有没有办法在屏幕上打印这个签名,给定(.),digitToInt以及我想将前者应用于后者的“信息”?
对于谁感兴趣,这个问题早先作为这个问题的副本被关闭了。
haskell types type-systems functional-programming polymorphic-functions
在Scala MEAP v10中的功能编程一书中,作者提到了这一点
多态函数通常受其类型约束,因此它们只有一个实现!
并举例说明
def partial1[A,B,C](a: A, f: (A,B) => C): B => C = (b: B) => f(a, b)
Run Code Online (Sandbox Code Playgroud)
这句话是什么意思?多态函数是否具有限制性?
例如,我如何编写一个版本的版本map将与Typed Racket中的多态函数一起使用?我使用一个简单的id函数定义为:
(: id : (All (A) A -> A))
(define (id x) x)
Run Code Online (Sandbox Code Playgroud)
当我尝试将其映射到列表时,我收到一个错误:
> (map id '(1 2 3))
Type Checker: Polymorphic function `map' could not be applied to arguments:
Types: (-> a b ... b c) (Listof a) (Listof b) ... b -> (Listof c)
(-> a c) (Pairof a (Listof a)) -> (Pairof c (Listof c))
Arguments: (All (A) (-> A A)) (List One Positive-Byte Positive-Byte)
Expected result: AnyValues
in: (map id …Run Code Online (Sandbox Code Playgroud) types higher-order-functions racket polymorphic-functions typed-racket
我有这种情况(剥离到必要部分)
class Foo[L <: HList](columns: L) {
class toRecord(row: Row) extends Poly1 {
implicit def caseColumn[T] = at[Column[T]] { /* map to a record field */ }
}
def asRecord = {
val resultSet: Stream[Row] = // computation to get result set
resultSet.map { row =>
val m = new toRecord(row) // this can't work
columns.map(m)
}
}
}
Run Code Online (Sandbox Code Playgroud)
这不起作用,因为map想要一个稳定的标识符,m而不是.所以我需要Poly1 singleton objects在结果集中有多少行.
这是与此处讨论的问题相同的问题:https://groups.google.com/forum/#!topic /shapeless-dev/P5DXRgnzqkY,但我无法找到使其工作的方法.
在链接的讨论中,Miles Sabin提出了folda Poly2而不是a …
我没有看到这个实现中的错误:
CREATE FUNCTION foo(anyelement) RETURNS SETOF int AS $f$
SELECT id FROM unnest(array[1,2,3]) t(id)
WHERE CASE WHEN (pg_typeof($1)::text)='integer' THEN $1::int>2 ELSE true END
$f$ LANGUAGE SQL IMMUTABLE;
SELECT * FROM foo(123); -- OK!
SELECT * FROM foo('test'::text); -- BUG
Run Code Online (Sandbox Code Playgroud)
这是某种 PostgreSQL 错误还是对anyelement数据类型的未记录限制?
有趣的是:当孤立时,该CASE子句可以正常工作:
CREATE FUNCTION bar(anyelement) RETURNS boolean AS $f$
SELECT CASE WHEN (pg_typeof($1)::text)='integer' THEN $1::int>2;
$f$ LANGUAGE SQL IMMUTABLE;
SELECT bar('test'::text), bar(123), bar(1); -- works fine!
Run Code Online (Sandbox Code Playgroud) 假设我需要不同的输出,具体取决于函数的多态参数的类型.我的初始尝试失败了一些神秘的错误消息:
choice :: a -> Int
choice (_ :: Int) = 0
choice (_ :: String) = 1
choice _ = 2
Run Code Online (Sandbox Code Playgroud)
但是,我们可以通过将所需类型包装在不同的数据构造函数中并在模式匹配中使用它们来轻松解决这个问题:
data Choice a = IntChoice Int | StringChoice String | OtherChoice a
choice :: Choice a -> Int
choice (IntChoice _) = 0
choice (StringChoice _) = 1
choice (OtherChoice _) = 2
Run Code Online (Sandbox Code Playgroud)
问题:你知道如何绕过这个吗?Haskell2010,GHC或任何扩展中是否有一个功能允许我使用第一个变体(或类似的东西)?
我遇到过这个功能
iter p f x = if (p x) then x else (iter p f (f x))
Run Code Online (Sandbox Code Playgroud)
我以为我会自己定义多态类型来理解这个概念.
我的想法如下:
该函数有3个参数,所以我们有 t1 -> t2 -> t3 -> T
p正在if条件中使用bool,因此必须返回at1 = a -> Bool
f也是p因为它在else块中作为参数传递的类型相同t2 = a -> Bool
x正在if条件中使用,因此它必须返回bool t1 = a -> Bool
但是当我检查ghci中的类型时,他们给我的类型是
iter :: (t -> Bool) -> (t -> t) -> t -> t
有人可以解释一下这背后的原因.
谢谢
我试图定义以下函数的多态类型:
flip f x y = f y x
Run Code Online (Sandbox Code Playgroud)
我的想法如下:
第一个参数flip,f取两个参数(t1 -> t2 -> t3)
由于函数内部的参数flip,x属于第二个参数类型.t1t1f
第三个参数flip,由于函数内部的参数y而属于类型.t3t3f
我不知道整体回报的多态类型.
但是当我检查ghci中的类型时,我得到:
flip :: (t2 -> t1 -> t) -> t1 -> t2 -> t
Run Code Online (Sandbox Code Playgroud)
有人可以请帮助通过这个例子是什么发生在这里?
谢谢
在Dotty 中给出以下内容:
object Domain {
final case class Create(name: String) extends BaseCreate[Create] {
override type Model = Domain
override def service[F[_]](client: KeystoneClient[F]): CrudService[F, Domain, Create] = client.domains
}
}
case class Domain(id: String)
class CrudService[F[_], Model, Create]
final class Domains[F[_]] extends CrudService[F, Domain, Domain.Create]
class KeystoneClient[F[_]] {
val domains = new Domains[F]
}
trait BaseCreate[Create <: BaseCreate[Create]] {
type Model
def service[F[_]](client: KeystoneClient[F]): CrudService[F, Model, Create]
}
Run Code Online (Sandbox Code Playgroud)
我想“简化” BaseCreate,以便我可以这样实现Create:
final case class Create(name: String) extends …Run Code Online (Sandbox Code Playgroud) 我对 Scala (特别是 Scala 3)有点陌生 - 所以我知道下面的问题可能是愚蠢的/na\xc3\xafve。
\n我知道下面的多态方法类型是有效的。
\ndef zeroMethod[A:Numeric] = Numeric[A].zero\nRun Code Online (Sandbox Code Playgroud)\n这里 Numeric 是泛型类型 A 上绑定的上下文。
\n请注意,\n scala> zeroMethod[Int]\n产量val res0: Int = 0。或者借助类型推断:
scala> val a = zeroMethod[Int]\nval a: Int = 0\nRun Code Online (Sandbox Code Playgroud)\n对此的稍微扩展是
\ndef zeroMethodFromVal[A:Numeric](x : A) = Numeric[A].zero \nRun Code Online (Sandbox Code Playgroud)\n该参数提供的唯一真正用途x是它有助于类型推断。
具体来说,
\nscala> zeroMethodFromVal(5)\nval res1: Int = 0\nRun Code Online (Sandbox Code Playgroud)\n从那时起,我想编写一个反映多态方法类型行为的多态函数类型。
\n如何向多态函数类型添加上下文边界?或者这是不可能的,因为上下文边界只是传递隐式参数的语法糖?
\n当我尝试创建一个与 等价的函数时zeroMethod,它给了我各种各样的错误......有些偏离了当前的主题。因此,我将省略该特定的代码片段。然而,似乎应该可以制作一个等效的函数zeroMethodFromVal,并且不会分散当前主题的注意力。
具体来说,我的(第一次)尝试是:
\n …types ×6
haskell ×4
scala ×4
function ×2
polymorphism ×2
dotty ×1
generics ×1
lambda ×1
postgresql ×1
racket ×1
scala-3 ×1
shapeless ×1
sql ×1
type-systems ×1
typed-racket ×1