初始点:
fn :: [a] -> Int
fn = (2 *) . length
Run Code Online (Sandbox Code Playgroud)
比方说,我们只是想约束的返回值,那么我们可以这样写:
fn list = (2 * length list) :: Int
Run Code Online (Sandbox Code Playgroud)
如何仅限制参数?简单.
fn list = 2 * length (list :: [Char])
Run Code Online (Sandbox Code Playgroud)
虽然这有效,但最好是收集顶部的签名而不是散布在函数体周围.
这是我能得到的最接近的:
fnSig = undefined :: [Char] -> a
fn | False = fnSig
| True = (* 2) . length
Run Code Online (Sandbox Code Playgroud)
基于http://okmij.org/ftp/Haskell/partial-signatures.lhs通过http://okmij.org/ftp/Haskell/types.html#partial-sigs
但是,我想要一个更清洁的解决方案.更好地沟通的东西,我的意图是部分限制.像这样的东西,例如:
fn :: [Char] -> a
fn = (2 *) . length
Run Code Online (Sandbox Code Playgroud)
或者可能:
fn :: [Char] -> _
fn …Run Code Online (Sandbox Code Playgroud) 是否可以为包含"空白"的Haskell值提供类型签名以填充类型推断算法?
背景的极为人为的例子:
m = return ('I', (("don't", "really"), "care", ["what", "this"], "type"), "is")
b = isJust m
Run Code Online (Sandbox Code Playgroud)
这有效.使用isJust m在b约束的类型m是Maybe <something>,和m的定义约束的类型m是<something> (Char, ((String, String), String, [String], String), String),并且编译器放在一起的那些信息两块制定出的精确类型m.
但是说我没有应用任何Maybe特定的功能m,所以我需要一个手动类型签名来阻止return多态.我不能这样说:
m :: Maybe a
m = return ('I', (("don't", "really"), "care", ["what", "this"], "type"), "is")
Run Code Online (Sandbox Code Playgroud)
因为那是不对的.该类型是不是Maybe a所有的a,它是Maybe a对一些a我想编译器来推断; 有在节目足够的信息让编译器做到这一点,我们可以从我的第一个例子中看到的编译器是能够放在一起多约束的类型,其中单独没有任何约束足以弄清楚什么类型的,但他们一起完全指定了类型.
我想要的是能够给出类型 …
这是从这个问题开始的.
为什么是:
... = ... x :: a ...
Run Code Online (Sandbox Code Playgroud)
未定义为
... = ... x `asTypeOf` (undefined :: a) ...
Run Code Online (Sandbox Code Playgroud)
即在赋值语句中,不是类型声明?
(注:a可以是任何东西,即Int,a或Maybe a)
作为一个额外的问题,什么代码会破坏定义x :: a为x `asTypeOf` (undefined :: a)?如何,它会使任何有效的代码无效或行为不同吗?