我正在使用smtp-mail库通过sendMailWithLogin函数从我的应用程序发送电子邮件。
我想知道电子邮件是否已成功发送或被退回。如果被退回,错误代码是什么?所有函数都返回IO ()
,深入研究代码会发现有很多层IO ()
。有没有办法用这个库来获取这些信息?或者也许还有其他可以使用的库?
我正在使用smtp-mail库通过sendMailWithLogin函数从我的应用程序发送电子邮件。
我想知道电子邮件是否已成功发送或被退回。如果被退回,错误代码是什么?所有函数都返回IO ()
,深入研究代码会发现有很多层IO ()
。有没有办法用这个库来获取这些信息?或者也许还有其他可以使用的库?
我有一些计算被标记为特定类型 (T) 的类型 ('A/'B)。我希望最终依赖于代码中的类型,因此我使用实例将类型映射回来:
data T = A | B -- also generates types 'A and 'B
class R (t :: T) where r :: Proxy t -> T
instance R 'A where r _ = A
instance R 'B where r _ = B
foo :: forall (t :: T) . R t => Bar T Int
foo = case r (Proxy :: Proxy t) of A -> ....
这没问题,但我想知道如果我有类型注释,我是否可以省去R t
一直写出约束的时间t
。是否可以重新组织此方案以更方便使用?谢谢。
(标题编辑:最初我写的是封闭类型家族,但这里它更像是给定类型的一组封闭类型。)
我正在尝试编写一个函数,该函数接受我的自定义类的类实例VectorSpace
(其形式为class VectorSpace t (n :: Nat) a where
)并对其执行高斯消元法。当前该函数如下所示:
rowEchelon
:: ( forall m. KnownNat m
, forall n. KnownNat n
, Field a
, VectorSpace t m a
, VectorSpace t n a
)
=> (forall k b. t k b -> Int -> b) -- ^ Indexing function
-> t m (t n a) -- ^ Matrix
-> t m (t n a) -- ^ Resultant row-echelon matrix
rowEchelon indexFunc = loop 0 0
where
loop h k matrix
| h >= mLen || k >= nLen = matrix
| otherwise = undefined
mLen = natVal (Proxy :: Proxy m)
nLen = natVal (Proxy :: Proxy n)
具有以下语言扩展:
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
但是,我收到以下错误:
• Illegal polymorphic type: forall (m1 :: Nat). KnownNat m1
A constraint must be a monotype
• In the type signature:
rowEchelon :: (forall m. KnownNat m,
forall n. KnownNat n,
Field a,
VectorSpace t m a,
VectorSpace t n a) =>
-- | Indexing function
(forall k b. t k b -> Int -> b)
-> -- | Matrix
t m (t n a)
-> -- | Resultant row-echelon matrix
t m (t n a)
• Perhaps you intended to use QuantifiedConstraints (typecheck)
但是添加QuantifiedConstraints
会导致在forall m. KnownNat m
和中出现以下警告forall n. KnownNat n
:
This binding for ‘[m or n depending on the line]’ shadows the existing binding
mLen
和上出现以下错误nLen
:
• Couldn't match kind ‘*’ with ‘GHC.Num.Natural.Natural’
When matching types
proxy0 :: Nat -> *
Proxy :: * -> *
Expected: proxy0 [n1 or n2]
Actual: Proxy n0
• In the first argument of ‘natVal’, namely ‘(Proxy :: Proxy [m or n])’
In the expression: natVal (Proxy :: Proxy [m or n])
In an equation for ‘nLen’: nLen = natVal (Proxy :: Proxy [m or n]) (typecheck -Wdeferred-type-errors)
我该如何解决这个打字冲突?
我尝试使用库regex-applicative。
我的代码是:
nicBeg = ((psym $ not . isSpace) $> (few anySym <> " adapter ")) *> some anySym
result = match nicBeg "abcd adapter NIC 1"
我 认为result
是 的Just "bcd adapter NIC 1"
.
但文献记载*>
表明:
*> :: forall (f :: Type -> Type) a b.Applicative f => fa -> fb -> fb
在‘GHC.Base’(base-4.16.4.0)中定义的
序列动作,丢弃第一个参数的值。
那么,问题是:为什么“bcd 适配器”部分存在于result
而不是只有“NIC 1”(它没有被丢弃)?是库的问题还是我哪里错了?
PS. 该库具有“贪婪” RE 表达式的概念。
PS. 很容易得到预期的结果:(((psym $ not . isSpace) *> (few anySym <> " adapter ")) *> some anySym
即替换$>
为*>
)
我有一个术语类型,其本质是:
data Term a = Term a Bool
deriving Show
这Bool
是一种辅助功能,只是偶尔需要。如果不需要,我希望用户可以跳过它。这意味着以下内容应该有效:
main :: IO ()
main = print v
where v = "a"
=: Term "b" True
=: []
在哪里:
class Join a b where
(=:) :: a -> [b] -> [b]
infixr 1 =:
instance Join a (Term a) where
x =: y = Term x False : y
instance Join (Term a) (Term a) where
x =: y = x : y
唉,GHC 抱怨道:
a.hs:15:8-12: error: [GHC-39999]
• Ambiguous type variable ‘b0’ arising from a use of ‘print’
prevents the constraint ‘(Show b0)’ from being solved.
Relevant bindings include v :: [b0] (bound at a.hs:17:8)
但如果我main
这样写:
main :: IO ()
main = print v
where v :: [Term String]
v = "a"
=: Term "b" True
=: []
那么一切都好了。(请注意,唯一的区别是我给出了v
类型签名。)
我很好奇是否存在一种现代 GHC 技巧(类型系列、Injective-Type-families、Closed-type-families、GADT 等,或者一些神奇的标志),可以使类型签名变得不必要,并让 GHC 无需任何帮助即可推断出类型本身。
以下是完整程序:
data Term a = Term a Bool
deriving Show
class Join a b where
(=:) :: a -> [b] -> [b]
infixr 1 =:
instance Join a (Term a) where
x =: y = Term x False : y
instance Join (Term a) (Term a) where
x =: y = x : y
main :: IO ()
main = print v
where v :: [Term String] -- Want to avoid this signature and let GHC deduce it.
v = "a"
=: Term "b" True
=: []
问题是,我是否可以应用一些 GHC 功能或技巧,这样v
就不需要类型签名了。我也很乐意更改Join
类或添加新参数/依赖项等,只要的局部定义v
可以按原样编写而无需类型签名。
如果有充分的正当理由说明我所要求的是不合理的,我也希望得到一个解释,说明为什么这是不可能的。在我看来,GHC 有足够的类型信息来推断类型本身,但我怀疑某种“开放世界”假设正在发挥作用,并且所有“封闭类型系列”之类的技巧都不会奏效;如果确实如此。要清楚的是,我很高兴该类Join
永远不会在任何其他类型上实例化。
有什么办法可以做到这一点?
type V = VList
{- type V2 a = V (V a)
type V4 a = V2 (V2 a)
type V8 a = V4 (V4 a)
type V16 a = V8 (V8 a)
type V32 a = V16 (V16 a) -}
type C a b c = a (b c)
type D a b = a b b
type E = D C
type V2 a = V (V a)
type V4 = E V2
type V8 = E V4
type V16 = E V8
type V32 = E V16
我想制作这种类型
type Vector25 = C (C V16 V8) V Empty
无需做
type Vector25 = (V16 (V8 (V Empty))
这是一个模块:
module Foo where
foo ws = let ws' = take 3 $ ws ++ repeat mempty
x = ws' !! 0
y = ws' !! 1
z = ws' !! 2
in [x, y, z]
这是另一个
module Foo where
foo ws = let (x:y:z:_) = take 3 $ ws ++ repeat mempty
in [x, y, z]
通过ghc -O2 -c foo.hs
,它们分别编译为 8072 和 5288 字节。不确定哪个最好,也不知道如何测试它们,但我猜它们在性能方面不可能表现完全相同,因为它们是不同的。
这两个函数的执行结果有什么不同吗?如果没有,那么生成的二进制文件中的差异是否是由于优化失误造成的?还是其他原因?
我有一个文件夹,里面全是 Haskell 的文学笔记,这些笔记按顺序排列如下:
\lhs_notes
'1 - Intro.lhs'
'2 - Seq.lhs'
...
并且每个文件都定义了一个模块Intro
,Seq
等等。有没有办法在.cabal
文件中为所有这些模块指定显式路径?因为出于组织目的,我想保留文件的名称,但我不知道如何让 cabal 找到这些模块中的任何一个。
在这里我尝试使用折叠重新实现安全最大值
import Data.ByteString (foldl')
maximum' :: Ord a => [a] -> Maybe a
maximum' = foldl (\ acc x -> max acc (Just x)) Nothing
maximum'' :: Ord a => [a] -> Maybe a
maximum'' = foldl' (\ acc x -> max acc (Just x)) Nothing
第一个使用 foldl 的函数工作正常,但第二个函数出现以下错误:
• Couldn't match expected type ‘a’
with actual type ‘GHC.Word.Word8’
‘a’ is a rigid type variable bound by
the type signature for:
maximum'' :: forall a. Ord a => [a] -> Maybe a
at /home/mali/Projects/Deneme/HigherOrder.hs:60:1-36
• In the first argument of ‘Just’, namely ‘x’
In the second argument of ‘max’, namely ‘(Just x)’
In the expression: max acc (Just x)
难道不应该foldl'
只是一个更有效的版本吗foldl
?
我一直在深入研究foldTree
Haskell中的函数,它的定义如下:
foldTree :: (a -> [b] -> b) -> Tree a -> b
foldTree f = go where
go (Node x ts) = f x (map go ts)
最近我偶然发现了对这句话的如下解释:
当我们调用时
f x vs
,我们假设x
和vs
已经与已知值绑定。
go (Node x ts) = f x (map go ts)
x
已经按照预期且熟悉的方式进行绑定。vs
;绑定vs
被推迟到整个子林的递归完成为止。提到时间元素(使用“已经”和“尚未”等术语)让我感到困惑。为了更好地理解这一点,我开始尝试一些从自然演绎和归纳证明中借用的概念。具体来说,我试图将第二个论点概念化f
如下:
[b]
。f
相结合来定义整体表达式,其中类型为。[b]
a
foldTree f tree
tree
Tree a
我如何才能在假设方面完善这种思路,而不是使用实际函数求值,假设它是正确的?或者,我是否可以采用另一种正式或直观的视角来更好地理解这个函数及其机制?