Jump to content

  • Log In with Google      Sign In   
  • Create Account


Making a C++ Either class based on Haskell's?


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
1 reply to this topic

#1 IFooBar   Members   -  Reputation: 906

Like
1Likes
Like

Posted 03 September 2012 - 05:34 AM

Hi guys,

I'm trying to play around in C++ a bit by making an Either class ala Haskell's. I have the basics working, but I want to be able to call a single "value()" member function of the Either class instead of calling first() when the first value is available and second() when the second value is available. Any hints on how to get that working? So far I have the following:

template<class First, class Second>
class Either
{
public:
	template<class T>
	Either<First, Second>& operator=(Either<T, Empty> &either) {
		first_ = either.value();
		hasFirst_ = true;
		return *this;
	}
	template<class T>
	Either<First, Second>& operator=(Either<Empty, T> &either) {
		second_ = either.value();
		hasFirst_ = false;
		return *this;
	}
	bool hasFirst() const { return hasFirst_; }
	bool hasSecond() const { return !hasFirst_; }
	const First& first() const { return first_; }
	const Second& second() const { return second_; }
private:
	union {
		First first_;
		Second second_;
	};
	bool hasFirst_;
};
template<class First>
class Either<First, Empty>
{
public:
	Either(const First &first)
		: first_(first)
	{}
	bool hasFirst() const { return true; }
	bool hasSecond() const { return false; }
	const First& value() const { return first_; }
private:
	First first_;
};
template<class Second>
class Either<Empty, Second>
{
public:
	Either(const Second &second)
		: second_(second)
	{}
	bool hasFirst() const { return false; }
	bool hasSecond() const { return true; }
	const Second& value() const { return second_; }
private:
	Second second_;
};
template<class First>
Either<First, Empty> makeEitherFirst(const First &first) {
	return Either<First, Empty>(first);
}
template<class Second>
Either<Empty, Second> makeEitherSecond(const Second &second) {
	return Either<Empty, Second>(second);
}

Also I've noticed perfect forwarding features of c++ 11 now, would it be possible to incorporate that in the operator = members of the Either template above. Maybe something like first_ = std::forward(either.value()). But that would require the parameters for the oepartor =() to take && values? I tried doing that but then I had to make the members && values as well, which meant I need to have appropriate default constructors.

Anyway to avoid that?

Currently this is my test code:
Seed::Either<int, float> result;
result = Seed::makeEitherFirst(3);
std::cout << result.first() << std::endl; // want this to be result.value() instead
result = Seed::makeEitherSecond(4.0);
std::cout << result.second() << std::endl; // want this to be result.value() instead

Thanks for any help!

Sponsor:

#2 GorbGorb   Members   -  Reputation: 112

Like
0Likes
Like

Posted 03 September 2012 - 06:27 AM

template<class First, class Second>
class Either
{
public:
	template<class T>
	Either<First, Second>& operator=(Either<T, Empty> either) {
		first_ = std::move( either.value() );
		hasFirst_ = true;
		return *this;
	}
	template<class T>
	Either<First, Second>& operator=(Either<Empty, T> either) {
		second_ = std::move( either.value() );
		hasFirst_ = false;
		return *this;
	}
	bool hasFirst() const { return hasFirst_; }
	bool hasSecond() const { return !hasFirst_; }
	const First& first() const { return first_; }
	const Second& second() const { return second_; }
private:
	union {
		First first_;
		Second second_;
	};
	bool hasFirst_;
};
This will eliminate unnecessary copies. Look at boost::variant, it does something similar.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS