这个问题在设计代码中已经出现过几次,特别是库.似乎有一些兴趣,所以我认为它可能会成为一个很好的社区维基.
failMonad中的方法被一些人认为是疣; 这个课程有点武断,不是来自原始范畴理论.但当然在当前状态下,许多Monad类型都有逻辑和有用的fail实例.
MonadPlus类是Monad的一个子类,它提供了mzero一种在monad中逻辑地封装失败概念的方法.
因此,想要编写一些执行某种失败处理fail的monadic代码的库设计人员可以选择让他的代码使用Monad中的方法或将他的代码限制为MonadPlus类,这样他就可以感觉良好的使用mzero,即使他完全不关心幺半群组合mplus操作.
关于这个主题的一些讨论在这个维基页面中有关改进MonadPlus课程的建议.
所以我想我有一个具体的问题:
什么monad实例,如果有的话,有一个自然的fail方法,但不能是MonadPlus的实例,因为它们没有逻辑实现mplus?
但我最感兴趣的是关于这个问题的讨论.谢谢!
编辑:最后一个想法发生在我身上.我最近学到了(尽管它在文档中是正确的fail),monadic"do"符号以模式匹配失败的方式被贬低,就像(x:xs) <- return []调用monad一样fail.
似乎语言设计者必须受到一些自动故障处理的前景的强烈影响,这些故障处理内置于haskell的语法中,包含fail在Monad中.
我正在努力研究在我正在处理的库中报告错误的一组函数中的错误的最佳方法.
具体来说,我的功能看起来像:
foo, bar, baz :: a -> Maybe a
Run Code Online (Sandbox Code Playgroud)
这里foo只能用一种方法(很适合可能会失败Maybe),但bar并baz可以以两种不同的方式失败每个(良好拟合的Either BarErrors和Either BazErrors).
一个解决方案是创建:
data AllTheErrors = TheFooError
| BarOutOfBeer
| BarBurnedDown
| ...
Run Code Online (Sandbox Code Playgroud)
并且使所有的功能恢复Either AllTheErrors,这表示可能通过提高误差范围组成的序列,这些功能在表达误差范围可能每个牺牲个别功能.
有没有办法可以同时获得两者?也许还有除了monadic组合之外的东西?或者与家庭类型(波浪手)...?
根据GHC 文档:
......如果完全应用GHC,GHC将仅内联函数,其中"完全应用"意味着应用于在函数定义的LHS上出现(语法上)的参数.
给出的示例是两个语义等效的定义:
comp1 :: (b -> c) -> (a -> b) -> a -> c
{-# INLINE comp1 #-}
comp1 f g = \x -> f (g x)
comp2 :: (b -> c) -> (a -> b) -> a -> c
{-# INLINE comp2 #-}
comp2 f g x = f (g x)
Run Code Online (Sandbox Code Playgroud)
我的问题:
只有在存在INLINE编译指示的情况下才能获得这种严格的行为(即LHS的严格句法视图,RHS内联w/out优化)?
没有给出INLINE编译指示时,也曾经GHC转换功能像comp2来comp1?
如果没有,为什么?编译器通常难以查看函数的语义并决定部分应用和INLINE的数量和位置?
如果GHC只是将所有函数转换为let... in带有lambda并且在LHS上没有绑定的级联表达式会发生什么?
有在短短的哈斯克尔平台单独(许多重叠的模块数泛型库syb,Data.Typeable,Data.Data,GHC.Generics),但我有一个非常基本的通用编程任务的麻烦.
我希望能够在相同形状的类型之间进行转换,即我想要在同构类型之间的多态,类型转换函数,本质上是本文末尾提供的(PDF),其中提到了索引类型族.
我并不关心废弃我的样板,而是能够围绕总和和产品抽象构建新的库.
下面的问题是GHC.Generic我认为最接近我需要的问题,但欢迎其他解决方案.
以下两种类型具有相同的形状
data Pair = Pair Char Int deriving (Generic, Show)
data Pair2 = Pair2 Char Int deriving (Generic, Show)
Run Code Online (Sandbox Code Playgroud)
我想使用GHC.Generics在它们之间转换值.由于所有幻像参数和其他废话,以下未能进行类型检查:
f :: Pair -> Pair2
f = to . from
Run Code Online (Sandbox Code Playgroud)
最终,我想要一个类似于fromInteger具有任何Generic(或任何其他类可支持此实例)实例的多态返回值的函数.我想我正在寻找类似的东西GHC.Generics:
--class:
type family NormalForm a
class ToGeneric a where
to :: a -> NormalForm a
class FromGeneric b where
from :: NormalForm b -> b
--examples:
data …Run Code Online (Sandbox Code Playgroud) Web开发人员目前在Web浏览器中实现客户端对等系统有哪些选择?一些假设的示例可能是文件共享服务,在客户找到彼此或聊天服务后绕过Web服务器.
我正在尝试优化一些代码,使用标准来尝试比较,例如,将INLINEpragma 添加到函数的效果.但我发现重新编译/运行之间的结果并不一致.
我需要知道如何使结果在运行中保持一致,以便我可以比较它们,或者如何评估基准是否可靠,即(我猜)如何解释方差的细节,"成本时钟呼叫"等
这与我上面的主要问题是正交的,但是在我的特定情况下,有几件事可能导致不一致:
我正在尝试使用基准测试IO操作,whnfIO因为whnf在此示例中使用的方法不起作用.
我的代码使用并发
我有很多标签和垃圾打开
这两个都来自相同的代码,以完全相同的方式编译.我直接在下面进行了第一次运行,做了一个更改并做了另一个基准测试,然后还原并再次运行第一个代码,编译:
ghc --make -fforce-recomp -threaded -O2 Benchmark.hs
Run Code Online (Sandbox Code Playgroud)
第一次运行:
estimating clock resolution...
mean is 16.97297 us (40001 iterations)
found 6222 outliers among 39999 samples (15.6%)
6055 (15.1%) high severe
estimating cost of a clock call...
mean is 1.838749 us (49 iterations)
found 8 outliers among 49 samples (16.3%)
3 (6.1%) high mild
5 (10.2%) high severe
benchmarking actors/insert 1000, query 1000
collecting …Run Code Online (Sandbox Code Playgroud) 在我正在编写的库中,我发现编写一个类似于(但略微更通用)以下类的类似乎是优雅的,它结合了通常uncurry的产品和fanin功能(从这里或在这里如果你更喜欢):
{-# LANGUAGE TypeOperators, TypeFamilies,MultiParamTypeClasses, FlexibleInstances #-}
import Prelude hiding(uncurry)
import qualified Prelude
class Uncurry t r where
type t :->-> r
uncurry :: (t :->-> r) -> t -> r
instance Uncurry () r where
type () :->-> r = r
uncurry = const
instance Uncurry (a,b) r where
type (a,b) :->-> r = a -> b -> r
uncurry = Prelude.uncurry
instance (Uncurry b c, Uncurry a c)=> Uncurry (Either …Run Code Online (Sandbox Code Playgroud) 我在unm-hip包中找到了这段代码.那么Pixel是一个功能?
class Imageable i where
type Pixel i :: *
rows :: i -> Int
cols :: i -> Int
ref :: i -> Int -> Int -> (Pixel i)
makeImage :: Int -> Int -> PixelOp (Pixel i) -> i
pixelList :: i -> [Pixel i]
pixelList i = [ ref i r c | r <- [0..(rows i - 1)], c <- [0..(cols i - 1)]]
Run Code Online (Sandbox Code Playgroud) 考虑以下:
do
x1 <- new 2
set x1 3
x2 <- get x1
y1 <- new 10
set y1 20
y2 <- get y1
return (x2 + y2)
Run Code Online (Sandbox Code Playgroud)
我想要这个结果23.有没有办法在纯Haskell中实现这样的东西,如果是这样的话怎么样?我理解STRef这样的事情,但我只是想在普通的Haskell中做到这一点(现在不担心效率).我认为我必须创建一个数据类型并使其成为实例Monad,但我不确定细节,所以一个有用的例子会有所帮助.
haskell ×9
ghc ×3
monads ×2
benchmarking ×1
composition ×1
flash ×1
generics ×1
html5 ×1
javascript ×1
optimization ×1
p2p ×1
state-monad ×1
typeclass ×1