此代码无法编译:
default ()
f :: RealFloat a => a
f = 1.0
g :: RealFloat a => a
g = 1.0
h :: Bool
h = f < g --Error. Ambiguous.
Run Code Online (Sandbox Code Playgroud)
这是预料之中的,因为它含糊不清.这两种可能性是Float
和Double
编译器不知道选择哪个<
.
但是,此代码确实编译:
default ()
f :: RealFloat a => a
f = 1.0
g :: RealFloat a => a
g = 1.0
h :: RealFloat a => a
h = f + g --Why does this compile?
Run Code Online (Sandbox Code Playgroud)
为什么?为什么Haskell在这里不会像上面的例子那样混淆,+
选择哪个(for Float …
代码
{-# LANGUAGE ScopedTypeVariables, TypeApplications #-}
-- I know this particular example is silly.
-- But that's not the point here.
g :: forall a . RealFloat a => Bool
g = True
main :: IO ()
main = print (g @Double)
Run Code Online (Sandbox Code Playgroud)
无法在GHC 8.0上编译并出现错误
• Could not deduce (RealFloat a0)
from the context: RealFloat a
bound by the type signature for:
g :: RealFloat a => Bool
at app/Main.hs:3:6-35
The type variable ‘a0’ is ambiguous
• In the ambiguity check …
Run Code Online (Sandbox Code Playgroud) 我想创建一个将Map k [v]
(Data.Map.Strict)转换为的函数Maybe (Map k v)
.
它的作用是:
Nothing
.Just
.我唯一能想到的是用foldrWithKey'
或手动完成foldlWithKey'
.还有更好的方法吗?
我有一个主要的Haskell可执行程序与cabal文件.在那里,我指定了ghc-options
.
这个可执行文件链接到荒野中的其他库.将ghc-options
这些库的阴谋文件被忽略?
我基本上想知道可执行文件是否ghc-options
将用于整个enchilada(主要的可执行文件+库).
其他赏金指出:还请扩大下面志的评论,即究竟是什么之间的差异ghc-options
为编译与链接.在图书馆中哪些是哪些,哪些是永远不需要的?也许你可以谈谈一些最重要的,如-threaded
下面提到的.
为什么guard
基于Alternative
?
guard :: Alternative f => Bool -> f ()
-- guard b is pure () if b is True,
-- and empty if b is False.
Run Code Online (Sandbox Code Playgroud)
我问因为guard
只使用了empty
来自Alternative
.它不使用<|>
从Alternative
根本.那么为什么要Alternative
首先使用呢?
我想这是因为背后有一些不成文的想法Alternative
的empty
,与我们正在努力与实现的目标完全吻合guard
(停止False
,继续True
).如果是这种情况,请告诉我这个没有说明的想法.
但与此同时,如果觉得我们只是在忽视<|>
.感觉好像guard
不是"完全捕捉"到底Alternative
是什么.我希望这是有道理的.为了使它更具体:为什么他们不发明另一个类似Stoppable
(或Abortable
)之类的类型并使用它而不是Alternative
?
我不完全理解为什么这样做很好:
[9223372036854775809..9223372036854775815] :: [Integer]
Run Code Online (Sandbox Code Playgroud)
那些是大于的整数maxBound :: Int
.然而,这些是两个关键Enum
功能的类型签名:
toEnum :: Int -> a
fromEnum :: a -> Int
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,它们Int
是有限的.
那么为什么上面的工作呢?
澄清:
我的问题是:enumFromTo
未定义toEnum
和fromEnum
?既然这两个只能用于常规的Int
s,那么enumFromTo
(对于哪个..
是语法糖)怎么能为Integer
s 工作呢?
假设我有一个函数,可以处理编译时已知大小的向量(这些由包提供vector-sized
):
{-# LANGUAGE DataKinds, GADTs #-}
module Test where
import Data.Vector.Sized
-- Processes vectors known at compile time to have size 4.
processVector :: Vector 4 Int -> String
processVector = undefined
Run Code Online (Sandbox Code Playgroud)
很好,但是如果我不想处理整数向量,而是向量向量怎么办?
-- Same thing but has subvectors of size 3.
processVector2 :: Vector 4 (Vector 3 Int) -> String
processVector2 = undefined
Run Code Online (Sandbox Code Playgroud)
很好,但是每个子向量都有固定的大小。我想要一个函数,其中子向量可以具有不同的大小,但在编译时仍然已知。
我们可以通过存在量化来做到这一点:
data InnerVector = forall n. InnerVector (Vector n Int)
processVector3 :: Vector 4 InnerVector -> String
processVector3 = undefined
Run Code Online (Sandbox Code Playgroud)
很好,但是如果我想返回的不是字符串而是相同维度的向量怎么办? …
这是在Haskell中获取Fibonacci序列的一种方法.这是来自书haskellbook.com(据说是初学者):
fibs = 1 : scanl (+) 1 fibs
Run Code Online (Sandbox Code Playgroud)
在手动写出一些第一个元素之后,我只能"看到"这是Fibonacci:
1 : scanl (+) 1 (1 : scanl (+) 1 (1 : scanl (+) 1 (1 : 1 ...
1 : scanl (+) 1 (1 : scanl (+) 1 (1 : 1 : 2 : 3 ...
1 : scanl (+) 1 (1 : 1 : 2 : 3 : 5 : 8 ...
1 : 1 : 2 : 3 : 5 : 8 : 13 : 21 ... …
Run Code Online (Sandbox Code Playgroud) 这很好用:
data Possibly a = LolNope | Yeppers a deriving (Eq, Show)
instance Functor Possibly where
fmap f (Yeppers a) = Yeppers (f a)
fmap _ LolNope = LolNope
Run Code Online (Sandbox Code Playgroud)
LolNope
在最后一行重复看起来并不优雅.用以下内容替换最后一行不起作用:
fmap _ z = z -- error: Couldn't match type ‘a’ with ‘b’ ...
Run Code Online (Sandbox Code Playgroud)
这也不起作用:
fmap _ z@(_) = z -- error: Couldn't match type ‘a’ with ‘b’ ...
Run Code Online (Sandbox Code Playgroud)
他们为什么不工作,有没有其他选择?
如预期的那样,可以正常工作:
valFrac :: Fractional a => a
valFrac = undefined
fNum :: Num a => a -> a
fNum a = undefined
resFrac :: Fractional a => a
resFrac = fNum valFrac -- Works as expected because every
-- Fractional is also a Num.
-- So as expected, we can pass
-- a Fractional argument into
-- a Num parameter.
Run Code Online (Sandbox Code Playgroud)
另一方面,以下方法也适用。我不明白为什么。
fFrac :: Fractional a => a -> a
fFrac a = undefined
valNum :: Num a => a
valNum …
Run Code Online (Sandbox Code Playgroud)