假设我有很多功能:
f :: a -> Maybe a
g :: a -> Maybe a
h :: a -> Maybe a
Run Code Online (Sandbox Code Playgroud)
我想用以下方式组合它们:如果f返回Nothing,则计算g.如果g返回Nothing,则计算h.如果其中任何一个计算Just a,请停止链.而整个构图(例如f)当然应该返回Maybe a.
这与Maybe monad的典型使用相反,如果返回Nothing,通常会停止计算.
用于链接这样的计算的Haskell成语是什么?
考虑一下我在设计一款大富翁游戏:
data Board = GO | A1 | CC1 | A2 | T1 | R1 | B1 | CH1 | B2 | B3 |
JAIL | C1 | U1 | C2 | C3 | R2 | D1 | CC2 | D2 | D3 |
FP | E1 | CH2 | E2 | E3 | R3 | F1 | F2 | U2 | F3 |
G2J | G1 | G2 | CC3 | G3 | R4 | CH3 | H1 | …Run Code Online (Sandbox Code Playgroud) 这是一个简单的程序,将我的堆炸到了王国来:
intersect n k z s rs c
| c == 23 = rs
| x == y = intersect (n+1) (k+1) (z+1) (z+s) (f : rs) (c+1)
| x < y = intersect (n+1) k (z+1) s rs c
| otherwise = intersect n (k+1) z s rs c
where x = (2*n*n) + 4 * n
y = (k * k + k )
f = (z, (x `div` 2), (z+s))
p = intersect 1 1 1 0 …Run Code Online (Sandbox Code Playgroud) 假设我有一个带变量参数的函数,比如sprintf().我想要的东西:
sprintf("%s %s", "a", "b")
Run Code Online (Sandbox Code Playgroud)
但我在矢量c("a","b")中有"a"和"b".像这样的电话
sprintf("%s %s", c("a", "b"))
Run Code Online (Sandbox Code Playgroud)
会因为参数不足而产生错误.许多语言提供了一种将矢量"展平"为可变长度参数的方法.但我似乎无法在R中找到这样做的语法.有办法吗?
我为没有提出这个问题的好标题而道歉.我在表达我需要的东西时遇到了一些麻烦.我在Haskell中有一个简单的问题,我想知道解决它的最佳方法是什么.
假设我有一个数字列表:[-3,2,1,2].我想返回具有最高绝对值的值.也就是说,我想返回-3.所以我想:
f = maximum . map abs
Run Code Online (Sandbox Code Playgroud)
当然,问题是返回计算值(3)而不是原始值(-3).
我可以想办法做到这一点,也许将原始列表映射到(originalValue,calculatdValue)元组,找到snd由我的函数返回的元组(最大值),然后返回该元组的fst.
但对于像这样的简单问题,这似乎有很多"管道",我想知道是否有一些我想念的抽象解决了这个问题.也就是说,我一直都会这样做,我想要一些巧妙的方法:
[-3,2,1,2],我想返回具有最高abs的值,那么我将返回-3).这有库函数吗?这有一个仿函数或一个monad吗?
我想我想要一个带签名的功能:
f :: ([b] -> b) -> (a -> b) -> [a] -> a
Run Code Online (Sandbox Code Playgroud)
即
f maximum abs [-3,2,1,2]
Run Code Online (Sandbox Code Playgroud)
这对我来说非常"乐观",或者可能是"monadic".
在编写从彼此继承的类型类时,我遇到了一个简单的问题.我正在尝试创建一个类型类的层次结构,以实现某种程度的表示抽象.假设我想要一个集合类型类:
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleInstances #-}
class Collection c a where
isMember :: a -> c -> Bool
Run Code Online (Sandbox Code Playgroud)
我已经定义了一个树类型:
data Tree a = Empty | Node a (Tree a) (Tree a)
deriving (Show, Eq)
Run Code Online (Sandbox Code Playgroud)
我想让我的树成为一个集合,所以:
inOrder :: Tree a -> [a]
inOrder Empty = []
inOrder (Node a l r) = (inOrder l) ++ [a] ++ (inOrder r)
instance (Eq a) => Collection (Tree a) a where
isMember a c = a `elem` (inOrder c)
Run Code Online (Sandbox Code Playgroud)
这不太正常:
*Main> …Run Code Online (Sandbox Code Playgroud) 我试图将我的大脑包裹在Haskell的存在类型中,我的第一个例子是可以显示的异构事物列表:
{-# LANGUAGE ExistentialQuantification #-}
data Showable = forall a. Show a => Showable a
showableList :: [Showable]
showableList = [Showable "frodo", Showable 1]
Run Code Online (Sandbox Code Playgroud)
现在在我看来,我想做的下一件事就是让Showable成为Show的一个实例,这样,例如,我的showableList可以显示在repl中:
instance Show Showable where
show a = ...
Run Code Online (Sandbox Code Playgroud)
我遇到的问题是我真正想要做的就是调用a的底层show实现.但是我在提到它时遇到了麻烦:
instance Show Showable where
show a = show a
Run Code Online (Sandbox Code Playgroud)
选择Showable在RHS上的show方法,这个方法在圈子里运行.我尝试了自动派生Show,但这不起作用:
data Showable = forall a. Show a => Showable a
deriving Show
Run Code Online (Sandbox Code Playgroud)
给我:
Can't make a derived instance of `Show Showable':
Constructor `Showable' does not have a Haskell-98 type
Possible …Run Code Online (Sandbox Code Playgroud) 假设我想使用类型类编写一个带有一些表示抽象的数独求解器.所以我想为行和矩阵创建一个类型类:
{-# LANGUAGE FlexibleInstances #-}
class Row r where
(!) :: r -> Int -> Int
class Sudoku a where
row :: (Row r) => Int -> a -> r
Run Code Online (Sandbox Code Playgroud)
显然,我会添加更多,但只是这些功能足以让我遇到麻烦.现在让我们说我想用嵌套列表来实现它.试:
instance Row r => Sudoku [r] where
row n s = s !! (n - 1)
Run Code Online (Sandbox Code Playgroud)
让我在热水中:
Couldn't match expected type `r1' against inferred type `r'
`r1' is a rigid type variable bound by
the type signature for `row' at 96b.hs:7:14
`r' is a rigid type variable bound by …Run Code Online (Sandbox Code Playgroud) 假设我有一些特征:
trait A[T] { def foo: T }
Run Code Online (Sandbox Code Playgroud)
扩展它的类:
class B[T](t: T) extends A[T] { def foo = t }
Run Code Online (Sandbox Code Playgroud)
和父特征的一个子特征:
trait C[T] extends A[T]
Run Code Online (Sandbox Code Playgroud)
我想将C与B混合使用。
val foo = new B("foo") with C[String]
Run Code Online (Sandbox Code Playgroud)
这可以正常工作,但是我不希望再次指定type参数,因为B已经是A [String]类型。但是,我知道Scala不支持以下功能:
val foo = new B("foo") with C
Run Code Online (Sandbox Code Playgroud)
我的问题是类型系统中还有其他机制可以支持在混合C时不必指定类型参数。我当时想的是:
trait C {
self: A[T] => ...
}
Run Code Online (Sandbox Code Playgroud)
有人会认为这种事情会解决将C混入其中的问题。但是,它不是有效的Scala。就像是:
trait C {
type T
self: A[T] =>
}
Run Code Online (Sandbox Code Playgroud)
也不起作用。
我想弄清楚我应该如何编写像Example.baz这样的方法:
class Foo {
type T
def send : T
}
class Bar {
type U
def receive(u: U)
}
class Example {
def baz(f: Foo, b: Bar) {
b.receive(f.send)
}
}
Run Code Online (Sandbox Code Playgroud)
显然,这只有在T = U的情况下才有意义,这就是我的意图.我只是不确定如何通知编译器这个意图.我觉得我正在消除一些非常明显的语言特征.
haskell ×7
scala ×2
heap-memory ×1
monads ×1
optimization ×1
polymorphism ×1
printf ×1
profiling ×1
r ×1
vector ×1